Skip to content

Commit ae84659

Browse files
Merge pull request #43 from nextcloud/fix-ocs-exception-handling
Add correct response for OCS*Exceptions
2 parents 5379789 + 9e44738 commit ae84659

File tree

6 files changed

+400
-2
lines changed

6 files changed

+400
-2
lines changed

src/ControllerMethod.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,12 @@ public static function parse(string $context, array $definitions, ClassMethod $m
8282
} else {
8383
$responseDescriptions[$statusCode] = $docNode->value->description;
8484
}
85-
$responses[] = new ControllerMethodResponse($docNode->value->type, $statusCode, "text/plain", new OpenApiType(type: "string"), null);
85+
86+
if (str_starts_with($type->name, 'OCS') && str_ends_with($type->name, 'Exception')) {
87+
$responses[] = new ControllerMethodResponse($docNode->value->type, $statusCode, "application/json", new OpenApiType(type: "array", maxLength: 0), null);
88+
} else {
89+
$responses[] = new ControllerMethodResponse($docNode->value->type, $statusCode, "text/plain", new OpenApiType(type: "string"), null);
90+
}
8691
}
8792
}
8893
}

src/Helpers.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ public static function mergeSchemas(array $schemas): mixed {
106106
}
107107

108108
public static function wrapOCSResponse(Route $route, ControllerMethodResponse $response, array|stdClass $schema): array|stdClass {
109-
if ($route->isOCS && $response->className == "DataResponse") {
109+
if ($route->isOCS
110+
&& ($response->className === 'DataResponse'
111+
|| (str_starts_with($response->className, 'OCS') && str_ends_with($response->className, 'Exception')))) {
110112
return [
111113
"type" => "object",
112114
"required" => [

tests/appinfo/routes.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,7 @@
6363
['name' => 'Settings#numericParameter', 'url' => '/api/{apiVersion}/numeric', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
6464
['name' => 'Settings#arrayListParameter', 'url' => '/api/{apiVersion}/array-list', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
6565
['name' => 'Settings#arrayKeyedParameter', 'url' => '/api/{apiVersion}/array-keyed', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
66+
['name' => 'Settings#throwingOCS', 'url' => '/api/{apiVersion}/throwing/ocs', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
67+
['name' => 'Settings#throwingOther', 'url' => '/api/{apiVersion}/throwing/other', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
6668
],
6769
];

tests/lib/Controller/SettingsController.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI;
3232
use OCP\AppFramework\Http\Attribute\OpenAPI;
3333
use OCP\AppFramework\Http\DataResponse;
34+
use OCP\AppFramework\OCS\OCSNotFoundException;
3435
use OCP\AppFramework\OCSController;
3536

3637
/**
@@ -410,4 +411,32 @@ public function arrayListParameter(array $value = ['test']): DataResponse {
410411
public function arrayKeyedParameter(array $value = ['test' => 'abc']): DataResponse {
411412
return new DataResponse();
412413
}
414+
415+
/**
416+
* @NoAdminRequired
417+
*
418+
* Route throws an OCS exception
419+
*
420+
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
421+
* @throws OCSNotFoundException Description of 404 because we throw all the time
422+
*
423+
* 200: Admin settings updated
424+
*/
425+
public function throwingOCS(): DataResponse {
426+
throw new OCSNotFoundException();
427+
}
428+
429+
/**
430+
* @NoAdminRequired
431+
*
432+
* Route throws an OCS exception
433+
*
434+
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
435+
* @throws NotFoundException Description of 404 because we throw all the time
436+
*
437+
* 200: Admin settings updated
438+
*/
439+
public function throwingOther(): DataResponse {
440+
throw new NotFoundException();
441+
}
413442
}

tests/openapi-full.json

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2963,6 +2963,186 @@
29632963
}
29642964
}
29652965
},
2966+
"/ocs/v2.php/apps/notifications/api/{apiVersion}/throwing/ocs": {
2967+
"post": {
2968+
"operationId": "settings-throwingocs",
2969+
"summary": "Route throws an OCS exception",
2970+
"tags": [
2971+
"settings"
2972+
],
2973+
"security": [
2974+
{
2975+
"bearer_auth": []
2976+
},
2977+
{
2978+
"basic_auth": []
2979+
}
2980+
],
2981+
"parameters": [
2982+
{
2983+
"name": "apiVersion",
2984+
"in": "path",
2985+
"required": true,
2986+
"schema": {
2987+
"type": "string",
2988+
"enum": [
2989+
"v2"
2990+
],
2991+
"default": "v2"
2992+
}
2993+
},
2994+
{
2995+
"name": "OCS-APIRequest",
2996+
"in": "header",
2997+
"description": "Required to be true for the API request to pass",
2998+
"required": true,
2999+
"schema": {
3000+
"type": "boolean",
3001+
"default": true
3002+
}
3003+
}
3004+
],
3005+
"responses": {
3006+
"200": {
3007+
"description": "Admin settings updated",
3008+
"content": {
3009+
"application/json": {
3010+
"schema": {
3011+
"type": "object",
3012+
"required": [
3013+
"ocs"
3014+
],
3015+
"properties": {
3016+
"ocs": {
3017+
"type": "object",
3018+
"required": [
3019+
"meta",
3020+
"data"
3021+
],
3022+
"properties": {
3023+
"meta": {
3024+
"$ref": "#/components/schemas/OCSMeta"
3025+
},
3026+
"data": {}
3027+
}
3028+
}
3029+
}
3030+
}
3031+
}
3032+
}
3033+
},
3034+
"404": {
3035+
"description": "Description of 404 because we throw all the time",
3036+
"content": {
3037+
"application/json": {
3038+
"schema": {
3039+
"type": "object",
3040+
"required": [
3041+
"ocs"
3042+
],
3043+
"properties": {
3044+
"ocs": {
3045+
"type": "object",
3046+
"required": [
3047+
"meta",
3048+
"data"
3049+
],
3050+
"properties": {
3051+
"meta": {
3052+
"$ref": "#/components/schemas/OCSMeta"
3053+
},
3054+
"data": {}
3055+
}
3056+
}
3057+
}
3058+
}
3059+
}
3060+
}
3061+
}
3062+
}
3063+
}
3064+
},
3065+
"/ocs/v2.php/apps/notifications/api/{apiVersion}/throwing/other": {
3066+
"post": {
3067+
"operationId": "settings-throwing-other",
3068+
"summary": "Route throws an OCS exception",
3069+
"tags": [
3070+
"settings"
3071+
],
3072+
"security": [
3073+
{
3074+
"bearer_auth": []
3075+
},
3076+
{
3077+
"basic_auth": []
3078+
}
3079+
],
3080+
"parameters": [
3081+
{
3082+
"name": "apiVersion",
3083+
"in": "path",
3084+
"required": true,
3085+
"schema": {
3086+
"type": "string",
3087+
"enum": [
3088+
"v2"
3089+
],
3090+
"default": "v2"
3091+
}
3092+
},
3093+
{
3094+
"name": "OCS-APIRequest",
3095+
"in": "header",
3096+
"description": "Required to be true for the API request to pass",
3097+
"required": true,
3098+
"schema": {
3099+
"type": "boolean",
3100+
"default": true
3101+
}
3102+
}
3103+
],
3104+
"responses": {
3105+
"200": {
3106+
"description": "Admin settings updated",
3107+
"content": {
3108+
"application/json": {
3109+
"schema": {
3110+
"type": "object",
3111+
"required": [
3112+
"ocs"
3113+
],
3114+
"properties": {
3115+
"ocs": {
3116+
"type": "object",
3117+
"required": [
3118+
"meta",
3119+
"data"
3120+
],
3121+
"properties": {
3122+
"meta": {
3123+
"$ref": "#/components/schemas/OCSMeta"
3124+
},
3125+
"data": {}
3126+
}
3127+
}
3128+
}
3129+
}
3130+
}
3131+
}
3132+
},
3133+
"500": {
3134+
"description": "Description of 404 because we throw all the time",
3135+
"content": {
3136+
"text/plain": {
3137+
"schema": {
3138+
"type": "string"
3139+
}
3140+
}
3141+
}
3142+
}
3143+
}
3144+
}
3145+
},
29663146
"/ocs/v2.php/apps/notifications/api/{apiVersion}/controller-scope": {
29673147
"post": {
29683148
"operationId": "federation-federation-by-controller",

0 commit comments

Comments
 (0)