Skip to content

Commit

Permalink
feat(polls): Define returned errors
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Oct 11, 2024
1 parent efebd69 commit 3a8660f
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 19 deletions.
11 changes: 6 additions & 5 deletions lib/Controller/PollController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use JsonException;
use OCA\Talk\Chat\ChatManager;
use OCA\Talk\Exceptions\PollPropertyException;
use OCA\Talk\Exceptions\WrongPermissionsException;
use OCA\Talk\Middleware\Attribute\FederationSupported;
use OCA\Talk\Middleware\Attribute\RequireModeratorOrNoLobby;
Expand Down Expand Up @@ -61,7 +62,7 @@ public function __construct(
* @psalm-param Poll::MODE_* $resultMode Mode how the results will be shown
* @param int $maxVotes Number of maximum votes per voter
* @param bool $draft Whether the poll should be saved as a draft (only allowed for moderators and with `talk-polls-drafts` capability)
* @return DataResponse<Http::STATUS_OK, TalkPollDraft, array{}>|DataResponse<Http::STATUS_CREATED, TalkPoll, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, TalkPollDraft, array{}>|DataResponse<Http::STATUS_CREATED, TalkPoll, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: 'draft'|'options'|'question'|'room'}, array{}>
*
* 200: Draft created successfully
* 201: Poll created successfully
Expand All @@ -82,11 +83,11 @@ public function createPoll(string $question, array $options, int $resultMode, in

if ($this->room->getType() !== Room::TYPE_GROUP
&& $this->room->getType() !== Room::TYPE_PUBLIC) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
return new DataResponse(['error' => PollPropertyException::REASON_ROOM], Http::STATUS_BAD_REQUEST);
}

if ($draft === true && !$this->participant->hasModeratorPermissions()) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
return new DataResponse(['error' => PollPropertyException::REASON_DRAFT], Http::STATUS_BAD_REQUEST);
}

$attendee = $this->participant->getAttendee();
Expand All @@ -102,9 +103,9 @@ public function createPoll(string $question, array $options, int $resultMode, in
$maxVotes,
$draft,
);
} catch (\Exception $e) {
} catch (PollPropertyException $e) {
$this->logger->error('Error creating poll', ['exception' => $e]);
return new DataResponse([], Http::STATUS_BAD_REQUEST);
return new DataResponse(['error' => $e->getReason()], Http::STATUS_BAD_REQUEST);
}

if ($draft) {
Expand Down
32 changes: 32 additions & 0 deletions lib/Exceptions/PollPropertyException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Talk\Exceptions;

class PollPropertyException extends \InvalidArgumentException {
public const REASON_DRAFT = 'draft';
public const REASON_QUESTION = 'question';
public const REASON_OPTIONS = 'options';
public const REASON_ROOM = 'room';

/**
* @param self::REASON_* $reason
*/
public function __construct(
protected string $reason,
) {
parent::__construct($reason);
}

/**
* @return self::REASON_*
*/
public function getReason(): string {
return $this->reason;
}
}
6 changes: 4 additions & 2 deletions lib/Federation/Proxy/TalkV1/Controller/PollController.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ public function votePoll(Room $room, Participant $participant, int $pollId, arra


/**
* @return DataResponse<Http::STATUS_OK, TalkPollDraft, array{}>|DataResponse<Http::STATUS_CREATED, TalkPoll, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, TalkPollDraft, array{}>|DataResponse<Http::STATUS_CREATED, TalkPoll, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, array{error: 'draft'|'options'|'question'|'room'}, array{}>
* @throws CannotReachRemoteException
*
* 200: Draft created successfully
* 201: Poll created successfully
* 400: Creating poll is not possible
*
Expand All @@ -150,7 +151,8 @@ public function createPoll(Room $room, Participant $participant, string $questio

$status = $proxy->getStatusCode();
if ($status === Http::STATUS_BAD_REQUEST) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
$data = $this->proxy->getOCSData($proxy, [Http::STATUS_BAD_REQUEST]);
return new DataResponse($data, Http::STATUS_BAD_REQUEST);
}

/** @var TalkPoll $data */
Expand Down
20 changes: 12 additions & 8 deletions lib/Service/PollService.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace OCA\Talk\Service;

use OCA\Talk\Exceptions\PollPropertyException;
use OCA\Talk\Exceptions\WrongPermissionsException;
use OCA\Talk\Model\Poll;
use OCA\Talk\Model\PollMapper;
Expand All @@ -29,23 +30,26 @@ public function __construct(
) {
}

/**
* @throws PollPropertyException
*/
public function createPoll(int $roomId, string $actorType, string $actorId, string $displayName, string $question, array $options, int $resultMode, int $maxVotes, bool $draft): Poll {
$question = trim($question);

if ($question === '' || strlen($question) > 32_000) {
throw new \UnexpectedValueException();
throw new PollPropertyException(PollPropertyException::REASON_QUESTION);
}

try {
json_encode($options, JSON_THROW_ON_ERROR, 1);
} catch (\Exception $e) {
throw new \RuntimeException();
} catch (\Exception) {
throw new PollPropertyException(PollPropertyException::REASON_OPTIONS);
}

$validOptions = [];
foreach ($options as $option) {
if (!is_string($option)) {
throw new \RuntimeException();
throw new PollPropertyException(PollPropertyException::REASON_OPTIONS);
}

$option = trim($option);
Expand All @@ -55,17 +59,17 @@ public function createPoll(int $roomId, string $actorType, string $actorId, stri
}

if (count($validOptions) < 2) {
throw new \RuntimeException();
throw new PollPropertyException(PollPropertyException::REASON_OPTIONS);
}

try {
$jsonOptions = json_encode($validOptions, JSON_THROW_ON_ERROR, 1);
} catch (\Exception $e) {
throw new \RuntimeException();
} catch (\Exception) {
throw new PollPropertyException(PollPropertyException::REASON_OPTIONS);
}

if (strlen($jsonOptions) > 60_000) {
throw new \UnexpectedValueException();
throw new PollPropertyException(PollPropertyException::REASON_OPTIONS);
}

$poll = new Poll();
Expand Down
18 changes: 17 additions & 1 deletion openapi-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -8889,7 +8889,23 @@
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
"data": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string",
"enum": [
"draft",
"options",
"question",
"room"
]
}
}
}
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -8776,7 +8776,23 @@
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
"data": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string",
"enum": [
"draft",
"options",
"question",
"room"
]
}
}
}
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/types/openapi/openapi-full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5188,7 +5188,10 @@ export interface operations {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
data: {
/** @enum {string} */
error: "draft" | "options" | "question" | "room";
};
};
};
};
Expand Down
5 changes: 4 additions & 1 deletion src/types/openapi/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4669,7 +4669,10 @@ export interface operations {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: unknown;
data: {
/** @enum {string} */
error: "draft" | "options" | "question" | "room";
};
};
};
};
Expand Down

0 comments on commit 3a8660f

Please sign in to comment.