From 3217c7a9800f679cd59faf10073adaf5c1761fa5 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 12:30:37 +0200 Subject: [PATCH 1/9] Create error handling documentation --- .../developer-resources/error-handling.md | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs/developer-docs/latest/developer-resources/error-handling.md diff --git a/docs/developer-docs/latest/developer-resources/error-handling.md b/docs/developer-docs/latest/developer-resources/error-handling.md new file mode 100644 index 0000000000..1b0ad9f024 --- /dev/null +++ b/docs/developer-docs/latest/developer-resources/error-handling.md @@ -0,0 +1,61 @@ +--- +title: Error handling - Strapi Developer Documentation +description: … +--- + + + +# Error handling + +Strapi has a standard format for errors that can be [returned](#receiving-errors) by the REST and GraphQL APIs or [thrown](#throwing-errors) by the customized parts of the Strapi backend. + +## Receiving errors + +Errors are included in the response object with the `errors` key and include information such as the HTTP status code, the name of the error, and additional information. + +### REST errors + +Errors thrown by the REST API are included in the [response](/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#unified-response-format) that has the following format: + +```json +{ + "data": null, + "error": { + "id?": "", // Autogenerated id that can be transmitted and followed along the stack + "status": "", // HTTP status + "name": "", // Strapi error name ('ApplicationError' or 'ValidationError') + "message": "", // A human reable error message + "meta": { + // error info specific to the error type + } + } +} +``` + + + +### GraphQL + +Errors thrown by the GraphQL API are included in the [response](/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.html#unified-response-format) that has the following format: + + +```json +{ + "data": null, + "error": { + "id?": "", // Autogenerated id that can be transmitted and followed along the stack + "status": "", // HTTP status + "name": "", // Strapi error name ('ApplicationError' or 'ValidationError') + "message": "", // A human reable error message + "meta": { + // error info specific to the error type + } + } +} +``` + +## Throwing errors + +The recommended way to throw errors when developing any custom logic with Strapi is to have the [controller](/developer-docs/latest/development/backend-customization/controllers.md) add a `badRequest` object to the [Koa's](https://koajs.com/#context) context. This `ctx.badRequest` object should contain error information that follows the proper format (see [receiving errors](#receiving-errors)). + +[Services](/developer-docs/latest/development/backend-customization/services.md) don't have access to the controller's `ctx` object. If services need to throw errors, these need to be caught by the controller, that in turn is in charge of sending the proper `ctx.badRequest` along with the response. From ece38db6d0f7b497ee43b79348aa6b994b7ccd5d Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 13:50:07 +0200 Subject: [PATCH 2/9] Add links in REST and GraphQL API docs --- .../developer-resources/database-apis-reference/graphql-api.md | 2 ++ .../developer-resources/database-apis-reference/rest-api.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.md b/docs/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.md index f1c476ff6f..d2f17c7ab4 100644 --- a/docs/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.md +++ b/docs/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.md @@ -20,6 +20,8 @@ Responses are unified with the GraphQL API in that: - queries and mutations that return information for a single entry mainly use a `XxxEntityResponse` type - queries and mutations that return i️nformation for multiple entries mainly use a `XxxEntityResponseCollection` type, which includes `meta` information (with [pagination](#pagination)) in addition to the data itself +Responses can also include an `error` (see [error handling documentation](/developer-docs/latest/developer-resources/error-handling.md)). + ::: details Example: Response formats for queries and mutations with an example 'Article' content-type ```graphql diff --git a/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md b/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md index e9a4465b17..0922947e4a 100644 --- a/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md +++ b/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md @@ -145,7 +145,7 @@ Whatever the query, the response is always an object with the following keys: - `meta`(object): information about pagination, publication state, available locales, etc. -- `error` (object, _optional_): information about any error thrown by the request +- `error` (object, _optional_): information about any [error](/developer-docs/latest/developer-resources/error-handling.md) thrown by the request ### Get entries From 74a0c51d884ee11fc5fd62fda5b5f4e6af7bea84 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 13:50:22 +0200 Subject: [PATCH 3/9] Add entry in sidebar TOC --- docs/.vuepress/config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 1ff86049fc..3390b7490f 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -307,6 +307,7 @@ const sidebar = { ] }, ['/developer-docs/latest/developer-resources/cli/CLI', 'Command Line Interface'], + ['/developer-docs/latest/developer-resources/error-handling.md', 'Error handling'], ], }, { From ab13ec03f5fe7fe58536daf5dcf6e1cc0daac4d3 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 15:50:15 +0200 Subject: [PATCH 4/9] Make h3 titles consistent --- .../developer-docs/latest/developer-resources/error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/developer-resources/error-handling.md b/docs/developer-docs/latest/developer-resources/error-handling.md index 1b0ad9f024..5e6bdfd8ce 100644 --- a/docs/developer-docs/latest/developer-resources/error-handling.md +++ b/docs/developer-docs/latest/developer-resources/error-handling.md @@ -34,7 +34,7 @@ Errors thrown by the REST API are included in the [response](/developer-docs/lat -### GraphQL +### GraphQL errors Errors thrown by the GraphQL API are included in the [response](/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.html#unified-response-format) that has the following format: From 04161497d56107c17873f7c10bd167a49c63cf25 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 15:54:01 +0200 Subject: [PATCH 5/9] Improve wording --- .../developer-docs/latest/developer-resources/error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/developer-resources/error-handling.md b/docs/developer-docs/latest/developer-resources/error-handling.md index 5e6bdfd8ce..469418b185 100644 --- a/docs/developer-docs/latest/developer-resources/error-handling.md +++ b/docs/developer-docs/latest/developer-resources/error-handling.md @@ -56,6 +56,6 @@ Errors thrown by the GraphQL API are included in the [response](/developer-docs/ ## Throwing errors -The recommended way to throw errors when developing any custom logic with Strapi is to have the [controller](/developer-docs/latest/development/backend-customization/controllers.md) add a `badRequest` object to the [Koa's](https://koajs.com/#context) context. This `ctx.badRequest` object should contain error information that follows the proper format (see [receiving errors](#receiving-errors)). +The recommended way to throw errors when developing any custom logic with Strapi is to have the [controller](/developer-docs/latest/development/backend-customization/controllers.md) add a `badRequest` object to the context (i.e. `ctx`) based on [Koa's](https://koajs.com/#context) context. This `ctx.badRequest` object should contain error information that follows the proper format (see [receiving errors](#receiving-errors)). [Services](/developer-docs/latest/development/backend-customization/services.md) don't have access to the controller's `ctx` object. If services need to throw errors, these need to be caught by the controller, that in turn is in charge of sending the proper `ctx.badRequest` along with the response. From 2af5547a8b1964874e9aa52f8b51c46adf91490a Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 4 Nov 2021 18:16:02 +0100 Subject: [PATCH 6/9] Update docs/developer-docs/latest/developer-resources/error-handling.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Pierre Noël --- .../developer-docs/latest/developer-resources/error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/developer-resources/error-handling.md b/docs/developer-docs/latest/developer-resources/error-handling.md index 469418b185..6618529360 100644 --- a/docs/developer-docs/latest/developer-resources/error-handling.md +++ b/docs/developer-docs/latest/developer-resources/error-handling.md @@ -11,7 +11,7 @@ Strapi has a standard format for errors that can be [returned](#receiving-errors ## Receiving errors -Errors are included in the response object with the `errors` key and include information such as the HTTP status code, the name of the error, and additional information. +Errors are included in the response object with the `error` key and include information such as the HTTP status code, the name of the error, and additional information. ### REST errors From c5f4f967cd2e01f169d92cf0a80375e3b9dc9cef Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 4 Nov 2021 18:22:21 +0100 Subject: [PATCH 7/9] Update JSONs --- .../developer-resources/error-handling.md | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/developer-docs/latest/developer-resources/error-handling.md b/docs/developer-docs/latest/developer-resources/error-handling.md index 6618529360..99ecd9191c 100644 --- a/docs/developer-docs/latest/developer-resources/error-handling.md +++ b/docs/developer-docs/latest/developer-resources/error-handling.md @@ -21,7 +21,6 @@ Errors thrown by the REST API are included in the [response](/developer-docs/lat { "data": null, "error": { - "id?": "", // Autogenerated id that can be transmitted and followed along the stack "status": "", // HTTP status "name": "", // Strapi error name ('ApplicationError' or 'ValidationError') "message": "", // A human reable error message @@ -38,18 +37,22 @@ Errors thrown by the REST API are included in the [response](/developer-docs/lat Errors thrown by the GraphQL API are included in the [response](/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.html#unified-response-format) that has the following format: - ```json -{ - "data": null, - "error": { - "id?": "", // Autogenerated id that can be transmitted and followed along the stack - "status": "", // HTTP status - "name": "", // Strapi error name ('ApplicationError' or 'ValidationError') - "message": "", // A human reable error message - "meta": { - // error info specific to the error type +{ "errors": [ + { + "message": "", // A human reable error message + "extensions": { + "error": { + "name": "", // Strapi error name ('ApplicationError' or 'ValidationError'), + "message": "", // A human reable error message (same one as above); + "details": {}, // Error info specific to the error type + }, + "code": "" // GraphQL error code (ex: BAD_USER_INPUT) + } } + ], + "data": { + "graphQLQueryName": null } } ``` From eb8e55e15e1f1b47971163eed2e80ad5d09a794d Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Thu, 4 Nov 2021 19:06:12 +0100 Subject: [PATCH 8/9] =?UTF-8?q?Improve=20based=20on=20M=C3=A9gane's=20and?= =?UTF-8?q?=20Pierre=20N's=20feedback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../developer-resources/error-handling.md | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/developer-docs/latest/developer-resources/error-handling.md b/docs/developer-docs/latest/developer-resources/error-handling.md index 99ecd9191c..de8b1be42c 100644 --- a/docs/developer-docs/latest/developer-resources/error-handling.md +++ b/docs/developer-docs/latest/developer-resources/error-handling.md @@ -7,7 +7,12 @@ description: … # Error handling -Strapi has a standard format for errors that can be [returned](#receiving-errors) by the REST and GraphQL APIs or [thrown](#throwing-errors) by the customized parts of the Strapi backend. +Strapi is natively handling errors with a standard format. + +There are 2 use cases for error handling: + +- As a developer querying content through the [REST](/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md) or [GraphQL](/developer-docs/latest/developer-resources/database-apis-reference/graphql-api.md) APIs, you might [receive errors](#receiving-errors) in response to the requests. +- As a developer customizing the backend of your Strapi application, you could use controllers and services to [throw errors](#throwing-errors). ## Receiving errors @@ -24,7 +29,7 @@ Errors thrown by the REST API are included in the [response](/developer-docs/lat "status": "", // HTTP status "name": "", // Strapi error name ('ApplicationError' or 'ValidationError') "message": "", // A human reable error message - "meta": { + "details": { // error info specific to the error type } } @@ -59,6 +64,32 @@ Errors thrown by the GraphQL API are included in the [response](/developer-docs/ ## Throwing errors -The recommended way to throw errors when developing any custom logic with Strapi is to have the [controller](/developer-docs/latest/development/backend-customization/controllers.md) add a `badRequest` object to the context (i.e. `ctx`) based on [Koa's](https://koajs.com/#context) context. This `ctx.badRequest` object should contain error information that follows the proper format (see [receiving errors](#receiving-errors)). +The recommended way to throw errors when developing any custom logic with Strapi is to have the [controller](/developer-docs/latest/development/backend-customization/controllers.md) respond with the correct status and body. + +This can be done by calling an error function on the context (i.e. `ctx`). Available error functions are listed in the [http-errors documentation](https://github.com/jshttp/http-errors#list-of-all-constructors) but their name should be camel-cased to be used by Strapi (e.g. `badRequest`). + +Error functions accept 2 parameters that correspond to the `error.message` and `error.details` attributes [received](#receiving-errors) by a developer querying the API: + +- the first parameter of the function is the error `message` +- and the second one is the object that will be set as `details` in the response received + +```js + +// path: ./src/api/[api-name]/controllers/my-controller.js + +module.exports = { + exampleAction: async (ctx, next) => { + try { + ctx.body = 'ok'; + } catch (err) { + // … + return ctx.badRequest('name is missing', { foo: 'bar' }). + } + } +} + +``` -[Services](/developer-docs/latest/development/backend-customization/services.md) don't have access to the controller's `ctx` object. If services need to throw errors, these need to be caught by the controller, that in turn is in charge of sending the proper `ctx.badRequest` along with the response. +:::note +[Services](/developer-docs/latest/development/backend-customization/services.md) don't have access to the controller's `ctx` object. If services need to throw errors, these need to be caught by the controller, that in turn is in charge of sending the proper error function. +::: From 25d98c4e8dfd7c3bbb179542f2f4a3ab30b766b5 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Mon, 8 Nov 2021 15:54:40 +0100 Subject: [PATCH 9/9] Update with Pierre N feedback --- .../latest/developer-resources/error-handling.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/developer-docs/latest/developer-resources/error-handling.md b/docs/developer-docs/latest/developer-resources/error-handling.md index de8b1be42c..68fee1afa3 100644 --- a/docs/developer-docs/latest/developer-resources/error-handling.md +++ b/docs/developer-docs/latest/developer-resources/error-handling.md @@ -78,18 +78,17 @@ Error functions accept 2 parameters that correspond to the `error.message` and ` // path: ./src/api/[api-name]/controllers/my-controller.js module.exports = { - exampleAction: async (ctx, next) => { - try { - ctx.body = 'ok'; - } catch (err) { - // … - return ctx.badRequest('name is missing', { foo: 'bar' }). + renameDog: async (ctx, next) => { + const newName = ctx.request.body.name; + if (!newName) { + return ctx.badRequest('name is missing', { foo: 'bar' }) } + ctx.body = strapi.service('api::dog.dog').rename(newName); } } ``` :::note -[Services](/developer-docs/latest/development/backend-customization/services.md) don't have access to the controller's `ctx` object. If services need to throw errors, these need to be caught by the controller, that in turn is in charge of sending the proper error function. +[Services](/developer-docs/latest/development/backend-customization/services.md) don't have access to the controller's `ctx` object. If services need to throw errors, these need to be caught by the controller, that in turn is in charge of calling the proper error function. :::