Skip to content

Commit 370af68

Browse files
jenkins-botGerrit Code Review
authored andcommitted
Merge "REST: Modify AddItemStatement to use exceptions"
2 parents 2d1cc94 + 119aa3b commit 370af68

File tree

8 files changed

+251
-275
lines changed

8 files changed

+251
-275
lines changed

repo/rest-api/src/RouteHandlers/AddItemStatementRouteHandler.php

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Wikibase\Repo\RestApi\RouteHandlers;
44

55
use Exception;
6-
use LogicException;
76
use MediaWiki\MediaWikiServices;
87
use MediaWiki\Rest\Handler;
98
use MediaWiki\Rest\RequestInterface;
@@ -19,9 +18,9 @@
1918
use Wikibase\Repo\RestApi\RouteHandlers\Middleware\UserAgentCheckMiddleware;
2019
use Wikibase\Repo\RestApi\Serialization\StatementSerializer;
2120
use Wikibase\Repo\RestApi\UseCases\AddItemStatement\AddItemStatement;
22-
use Wikibase\Repo\RestApi\UseCases\AddItemStatement\AddItemStatementErrorResponse;
2321
use Wikibase\Repo\RestApi\UseCases\AddItemStatement\AddItemStatementRequest;
24-
use Wikibase\Repo\RestApi\UseCases\AddItemStatement\AddItemStatementSuccessResponse;
22+
use Wikibase\Repo\RestApi\UseCases\AddItemStatement\AddItemStatementResponse;
23+
use Wikibase\Repo\RestApi\UseCases\UseCaseException;
2524
use Wikibase\Repo\RestApi\WbRestApi;
2625
use Wikimedia\ParamValidator\ParamValidator;
2726

@@ -95,23 +94,20 @@ public function run( ...$args ): Response {
9594
*/
9695
public function runUseCase( string $itemId ): Response {
9796
$jsonBody = $this->getValidatedBody();
98-
$useCaseResponse = $this->addItemStatement->execute(
99-
new AddItemStatementRequest(
100-
$itemId,
101-
$jsonBody[self::STATEMENT_BODY_PARAM],
102-
$jsonBody[self::TAGS_BODY_PARAM],
103-
$jsonBody[self::BOT_BODY_PARAM],
104-
$jsonBody[self::COMMENT_BODY_PARAM],
105-
$this->getUsername()
106-
)
107-
);
108-
109-
if ( $useCaseResponse instanceof AddItemStatementSuccessResponse ) {
97+
try {
98+
$useCaseResponse = $this->addItemStatement->execute(
99+
new AddItemStatementRequest(
100+
$itemId,
101+
$jsonBody[self::STATEMENT_BODY_PARAM],
102+
$jsonBody[self::TAGS_BODY_PARAM],
103+
$jsonBody[self::BOT_BODY_PARAM],
104+
$jsonBody[self::COMMENT_BODY_PARAM],
105+
$this->getUsername()
106+
)
107+
);
110108
return $this->newSuccessHttpResponse( $useCaseResponse, $itemId );
111-
} elseif ( $useCaseResponse instanceof AddItemStatementErrorResponse ) {
112-
return $this->responseFactory->newErrorResponse( $useCaseResponse );
113-
} else {
114-
throw new LogicException( 'Received an unexpected use case result in ' . __CLASS__ );
109+
} catch ( UseCaseException $e ) {
110+
return $this->responseFactory->newErrorResponseFromException( $e );
115111
}
116112
}
117113

@@ -156,7 +152,7 @@ public function getBodyValidator( $contentType ): BodyValidator {
156152
] ) : parent::getBodyValidator( $contentType );
157153
}
158154

159-
private function newSuccessHttpResponse( AddItemStatementSuccessResponse $useCaseResponse, string $itemId ): Response {
155+
private function newSuccessHttpResponse( AddItemStatementResponse $useCaseResponse, string $itemId ): Response {
160156
$httpResponse = $this->getResponseFactory()->create();
161157
$httpResponse->setStatus( 201 );
162158
$httpResponse->setHeader( 'Content-Type', 'application/json' );

repo/rest-api/src/UseCases/AddItemStatement/AddItemStatement.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Wikibase\Repo\RestApi\Domain\Services\ItemUpdater;
1313
use Wikibase\Repo\RestApi\Domain\Services\PermissionChecker;
1414
use Wikibase\Repo\RestApi\UseCases\ErrorResponse;
15+
use Wikibase\Repo\RestApi\UseCases\UseCaseException;
1516

1617
/**
1718
* @license GPL-2.0-or-later
@@ -42,33 +43,29 @@ public function __construct(
4243
}
4344

4445
/**
45-
* @return AddItemStatementSuccessResponse | AddItemStatementErrorResponse
46+
* @throws UseCaseException
4647
*/
47-
public function execute( AddItemStatementRequest $request ) {
48-
$validationError = $this->validator->validate( $request );
49-
50-
if ( $validationError ) {
51-
return AddItemStatementErrorResponse::newFromValidationError( $validationError );
52-
}
48+
public function execute( AddItemStatementRequest $request ): AddItemStatementResponse {
49+
$this->validator->assertValidRequest( $request );
5350

5451
$statement = $this->validator->getValidatedStatement();
5552
$itemId = new ItemId( $request->getItemId() );
5653

5754
$latestRevision = $this->revisionMetadataRetriever->getLatestRevisionMetadata( $itemId );
5855
if ( $latestRevision->isRedirect() ) {
59-
return new AddItemStatementErrorResponse(
56+
throw new UseCaseException(
6057
ErrorResponse::ITEM_REDIRECTED,
6158
"Item {$request->getItemId()} has been merged into {$latestRevision->getRedirectTarget()}."
6259
);
6360
} elseif ( !$latestRevision->itemExists() ) {
64-
return new AddItemStatementErrorResponse(
61+
throw new UseCaseException(
6562
ErrorResponse::ITEM_NOT_FOUND,
6663
"Could not find an item with the ID: {$request->getItemId()}"
6764
);
6865
}
6966
$user = $request->hasUser() ? User::withUsername( $request->getUsername() ) : User::newAnonymous();
7067
if ( !$this->permissionChecker->canEdit( $user, $itemId ) ) {
71-
return new AddItemStatementErrorResponse(
68+
throw new UseCaseException(
7269
ErrorResponse::PERMISSION_DENIED,
7370
'You have no permission to edit this item.'
7471
);
@@ -86,7 +83,7 @@ public function execute( AddItemStatementRequest $request ) {
8683
);
8784
$newRevision = $this->itemUpdater->update( $item, $editMetadata );
8885

89-
return new AddItemStatementSuccessResponse(
86+
return new AddItemStatementResponse(
9087
$newRevision->getItem()->getStatements()->getStatementById( $newStatementGuid ),
9188
$newRevision->getLastModified(),
9289
$newRevision->getRevisionId()

repo/rest-api/src/UseCases/AddItemStatement/AddItemStatementErrorResponse.php

Lines changed: 0 additions & 61 deletions
This file was deleted.

repo/rest-api/src/UseCases/AddItemStatement/AddItemStatementSuccessResponse.php renamed to repo/rest-api/src/UseCases/AddItemStatement/AddItemStatementResponse.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
/**
88
* @license GPL-2.0-or-later
99
*/
10-
class AddItemStatementSuccessResponse {
10+
class AddItemStatementResponse {
1111

1212
private Statement $statement;
1313
private string $lastModified;

repo/rest-api/src/UseCases/AddItemStatement/AddItemStatementValidator.php

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
namespace Wikibase\Repo\RestApi\UseCases\AddItemStatement;
44

55
use Wikibase\DataModel\Statement\Statement;
6+
use Wikibase\Repo\RestApi\UseCases\ErrorResponse;
7+
use Wikibase\Repo\RestApi\UseCases\UseCaseException;
68
use Wikibase\Repo\RestApi\Validation\EditMetadataValidator;
79
use Wikibase\Repo\RestApi\Validation\ItemIdValidator;
810
use Wikibase\Repo\RestApi\Validation\StatementValidator;
9-
use Wikibase\Repo\RestApi\Validation\ValidationError;
1011

1112
/**
1213
* @license GPL-2.0-or-later
@@ -27,15 +28,96 @@ public function __construct(
2728
$this->editMetadataValidator = $editMetadataValidator;
2829
}
2930

30-
public function validate( AddItemStatementRequest $request ): ?ValidationError {
31-
return $this->itemIdValidator->validate( $request->getItemId() ) ?:
32-
$this->statementValidator->validate( $request->getStatement() ) ?:
33-
$this->editMetadataValidator->validateComment( $request->getComment() ) ?:
34-
$this->editMetadataValidator->validateEditTags( $request->getEditTags() );
31+
/**
32+
* @throws UseCaseException
33+
*/
34+
public function assertValidRequest( AddItemStatementRequest $request ): void {
35+
$this->validateItemId( $request->getItemId() );
36+
$this->validateStatement( $request->getStatement() );
37+
$this->validateEditTags( $request->getEditTags() );
38+
$this->validateComment( $request->getComment() );
3539
}
3640

3741
public function getValidatedStatement(): ?Statement {
3842
return $this->statementValidator->getValidatedStatement();
3943
}
4044

45+
/**
46+
* @throws UseCaseException
47+
*/
48+
private function validateItemId( ?string $itemId ): void {
49+
if ( !isset( $itemId ) ) {
50+
return;
51+
}
52+
53+
$validationError = $this->itemIdValidator->validate( $itemId );
54+
55+
if ( $validationError ) {
56+
throw new UseCaseException(
57+
ErrorResponse::INVALID_ITEM_ID,
58+
'Not a valid item ID: ' . $validationError->getContext()[ItemIdValidator::CONTEXT_VALUE]
59+
);
60+
}
61+
}
62+
63+
/**
64+
* @throws UseCaseException
65+
*/
66+
private function validateStatement( array $statement ): void {
67+
$validationError = $this->statementValidator->validate( $statement );
68+
69+
if ( $validationError ) {
70+
switch ( $validationError->getCode() ) {
71+
case StatementValidator::CODE_INVALID_FIELD:
72+
throw new UseCaseException(
73+
ErrorResponse::STATEMENT_DATA_INVALID_FIELD,
74+
"Invalid input for '{$validationError->getContext()[StatementValidator::CONTEXT_FIELD_NAME]}'",
75+
[
76+
'path' => $validationError->getContext()[StatementValidator::CONTEXT_FIELD_NAME],
77+
'value' => $validationError->getContext()[StatementValidator::CONTEXT_FIELD_VALUE],
78+
]
79+
);
80+
case StatementValidator::CODE_MISSING_FIELD:
81+
throw new UseCaseException(
82+
ErrorResponse::STATEMENT_DATA_MISSING_FIELD,
83+
'Mandatory field missing in the statement data: ' .
84+
$validationError->getContext()[StatementValidator::CONTEXT_FIELD_NAME],
85+
[ 'path' => $validationError->getContext()[StatementValidator::CONTEXT_FIELD_NAME] ]
86+
);
87+
}
88+
}
89+
}
90+
91+
/**
92+
* @throws UseCaseException
93+
*/
94+
private function validateEditTags( array $editTags ): void {
95+
$validationError = $this->editMetadataValidator->validateEditTags( $editTags );
96+
97+
if ( $validationError ) {
98+
throw new UseCaseException(
99+
ErrorResponse::INVALID_EDIT_TAG,
100+
"Invalid MediaWiki tag: {$validationError->getContext()[EditMetadataValidator::CONTEXT_TAG_VALUE]}"
101+
);
102+
}
103+
}
104+
105+
/**
106+
* @throws UseCaseException
107+
*/
108+
private function validateComment( ?string $comment ): void {
109+
if ( !isset( $comment ) ) {
110+
return;
111+
}
112+
113+
$validationError = $this->editMetadataValidator->validateComment( $comment );
114+
115+
if ( $validationError ) {
116+
$commentMaxLength = $validationError->getContext()[EditMetadataValidator::CONTEXT_COMMENT_MAX_LENGTH];
117+
throw new UseCaseException(
118+
ErrorResponse::COMMENT_TOO_LONG,
119+
"Comment must not be longer than $commentMaxLength characters.",
120+
);
121+
}
122+
}
41123
}

0 commit comments

Comments
 (0)