From 2ee6e9bb73a5314fc270663384961929d70b53a8 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Wed, 2 Sep 2020 19:15:21 -0700 Subject: [PATCH 01/17] feat: AIP-193 This adds a generic AIP for errors. There is probably a decent bit for us to discuss here. Some high-level notes: - I decided to represent expected JSON interfaces using TypeScript (rather than JSONSchema), which I perceive to be much better for human readability. - We should discuss/debate the proposed Error interface. It is mostly similar to what Google uses but with two fields "promoted" (we have a huge _mea culpa_ here). - I did not discuss any common _headers_ related to error handling (e.g. `Retry-After`). I personally think that `Retry-After` gets covered in AIP-194, and I could not think of any others that warranted inclusion here. I expect this is an area where everyone will need to make changes, but I also notice that entire sections can probably be adopted by everyone (e.g. "Messages"), so I think this should work reasonably well. Looking forward to the discussion on this. --- aip/general/0193/aip.md | 117 ++++++++++++++++++++++++++++++++++++++ aip/general/0193/aip.yaml | 7 +++ 2 files changed, 124 insertions(+) create mode 100644 aip/general/0193/aip.md create mode 100644 aip/general/0193/aip.yaml diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md new file mode 100644 index 00000000..717f9f46 --- /dev/null +++ b/aip/general/0193/aip.md @@ -0,0 +1,117 @@ +# Errors + +Error handling is an important part of designing simple and intuitive APIs. +Consistent error handling allows developers to know how to expect to receive +errors, and to reduce boilerplate by having common error-handling logic, rather +than being expected to constantly add verbose error handling everywhere. + +## Guidance + +Services **must** clearly distinguish successful responses from error responses +by using appropriate HTTP codes: + +- Successful responses **must** use HTTP status codes between 200 and 399. +- Errors indicating a problem with the user's request **must** use HTTP status + codes between 400 and 499. +- Errors indicating a problem with the server's handling of an valid request + **must** use HTTP status codes between 500 and 599. + +### Structure + +Error responses **should** conform to the following interface: + +```typescript +interface Error { + // The HTTP status code. + code: number; + + // A developer-facing error message, in English. + message: string; + + // The source of the error (usually the registered service address of the + // tool or product that generates the error). + // Example: "pubsub.googleapis.com" + domain: string; + + // The type of the error. This is a constant value that identified the + // cause of the error, unique within a given domain, that developers write + // code against. + type: string; + + // An array of additional error details. + details: ?any[]; +} +``` + +- The `message` field is intended for consumption by humans, and therefore + **may** change, even within a single version. +- The `type` field is intended to have code written against it, and therefore + **must not** change. Values for this field should be 0-63 characters, and use + only lower-case letters, numbers, and the `-` character. +- The `domain` field is intended to provide a logical grouping for `type` + values, and **should** usually be set to the registered domain where the API + is served (such as `pubsub.googleapis.com`). + - If the error is generated by common internal infrastructure, the error + domain **must** be a globally-unique value that identifies the + infrastructure. +- The `details` field **may** contain any additional details that are useful, + including additional metadata or localized error messages. + +### Messages + +Error messages **should** help a reasonably technical user understand and +resolve the issue, and **should not** assume that the user is an expert in the +particular API. Additionally, error messages **must not** assume that the user +will know anything about its underlying implementation. + +Error messages **should** be brief but actionable. Any extra information +**should** be provided in a `details` field. If even more information is +necessary, the service **should** provide a link where a reader can get more +information or ask questions to help resolve the issue. + +### Localization + +Error messages **must** be in American English. If a localized error message is +also required, the service **should** provide the following structure within +its `details`: + +```typescript +interface LocalizedMessage { + // The locale for this error message. + // Follows the spec defined at http://www.rfc-editor.org/rfc/bcp/bcp47.txt. + // Examples: 'en-US', 'de-CH', 'es-MX' + locale: string; + + // The localized error message in the above locale. + message: string; +} +``` + +### Partial errors + +APIs **should not** support partial errors. Partial errors add significant +complexity for users, because they usually sidestep the use of error codes, or +move those error codes into the response message, where the user must write +specialized error handling logic to address the problem. + +However, occasionally partial errors are unavoidable, particularly in bulk +operations where it would be hostile to users to fail an entire large request +because of a problem with a single entry. + +Methods that require partial errors **should** use long-running operations (as +described in AIP-151), and the method **should** put partial failure +information in the metadata message. The errors themselves **must** still be +represented with an error object. + +## Further reading + +- For which error codes to retry, see AIP-194. + +## Changelog + +- **2020-09-02**: Refactored errors AIP to be more generic. +- **2020-01-22**: Added a reference to the `ErrorInfo` message in gRPC. +- **2019-10-14**: Added guidance restricting error message mutability to if + there is a machine-readable identifier present. +- **2019-09-23**: Added guidance about error message strings being able to + change. diff --git a/aip/general/0193/aip.yaml b/aip/general/0193/aip.yaml new file mode 100644 index 00000000..32f59908 --- /dev/null +++ b/aip/general/0193/aip.yaml @@ -0,0 +1,7 @@ +--- +id: 193 +state: approved +created: 2019-07-26 +placement: + category: polish + order: 30 From 1519d971308b3f23900bcb9d4c094bd03f131845 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 6 Dec 2021 15:28:30 -0800 Subject: [PATCH 02/17] Update aip.md --- aip/general/0193/aip.md | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 717f9f46..b5daab48 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -22,40 +22,30 @@ Error responses **should** conform to the following interface: ```typescript interface Error { - // The HTTP status code. - code: number; + //A machine-readable code indicating the type of error. This value is parseable for programmatic error handling. + code?: string; - // A developer-facing error message, in English. - message: string; + //A human readable description of the problem. Should not change from occurrence to occurrence (except for localization). + title?: string - // The source of the error (usually the registered service address of the - // tool or product that generates the error). - // Example: "pubsub.googleapis.com" - domain: string; + //The HTTP status code between 100 and 500 + status?: integer - // The type of the error. This is a constant value that identified the - // cause of the error, unique within a given domain, that developers write - // code against. - type: string; + //A human-readable explanation specific to this occurrence of the problem + detail?: string - // An array of additional error details. - details: ?any[]; + //A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. + id?: string } ``` -- The `message` field is intended for consumption by humans, and therefore +- The `title` field is intended for consumption by humans, and therefore **may** change, even within a single version. -- The `type` field is intended to have code written against it, and therefore +- The `code` field is intended to have code written against it, and therefore **must not** change. Values for this field should be 0-63 characters, and use only lower-case letters, numbers, and the `-` character. -- The `domain` field is intended to provide a logical grouping for `type` - values, and **should** usually be set to the registered domain where the API - is served (such as `pubsub.googleapis.com`). - - If the error is generated by common internal infrastructure, the error - domain **must** be a globally-unique value that identifies the - infrastructure. -- The `details` field **may** contain any additional details that are useful, - including additional metadata or localized error messages. + + ### Messages From 40cff574208569ea6bcc04e1ebfa33460191afd8 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 6 Dec 2021 16:05:27 -0800 Subject: [PATCH 03/17] Update aip.md --- aip/general/0193/aip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index b5daab48..35bbc954 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -9,7 +9,7 @@ than being expected to constantly add verbose error handling everywhere. Services **must** clearly distinguish successful responses from error responses by using appropriate HTTP codes: - +- Informational responses **must** use HTTP status codes between 100 and 199. - Successful responses **must** use HTTP status codes between 200 and 399. - Errors indicating a problem with the user's request **must** use HTTP status codes between 400 and 499. From 1aa3dee7c05fa6e470eda30458721f7b9dc620d7 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 6 Dec 2021 17:25:55 -0800 Subject: [PATCH 04/17] Update aip.md --- aip/general/0193/aip.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 35bbc954..c4def023 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -22,8 +22,8 @@ Error responses **should** conform to the following interface: ```typescript interface Error { - //A machine-readable code indicating the type of error. This value is parseable for programmatic error handling. - code?: string; + //A machine-readable code indicating the type of error (like `name_too_long`). This value is parseable for programmatic error handling. + code: string; //A human readable description of the problem. Should not change from occurrence to occurrence (except for localization). title?: string From 9172c5194a5a102a50a197cc346be8825561af5b Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 6 Dec 2021 18:01:11 -0800 Subject: [PATCH 05/17] adding example good errors --- aip/general/0193/aip.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index c4def023..f64a36d6 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -59,6 +59,17 @@ Error messages **should** be brief but actionable. Any extra information necessary, the service **should** provide a link where a reader can get more information or ask questions to help resolve the issue. +Below are some examples of good errors and not so good errors: + + ❌ Invalid Book Name. + ✅ Book name must be between 5 and 50 characters. + + ❌ Access is denied + ✅ Only admin users have access to this resource. + + ❌ Bad input + ✅ 'ID' must be provided in the input + ### Localization Error messages **must** be in American English. If a localized error message is From 6233a694d0d06a174edd2a849c990bfa505eda60 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Tue, 14 Dec 2021 10:12:38 -0800 Subject: [PATCH 06/17] Adding an errors array --- aip/general/0193/aip.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index f64a36d6..24307ece 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -22,22 +22,24 @@ Error responses **should** conform to the following interface: ```typescript interface Error { - //A machine-readable code indicating the type of error (like `name_too_long`). This value is parseable for programmatic error handling. + // A machine-readable code indicating the type of error (like `name_too_long`). This value is parseable for programmatic error handling. code: string; - //A human readable description of the problem. Should not change from occurrence to occurrence (except for localization). + // A human readable description of the problem. Should not change from occurrence to occurrence (except for localization). title?: string - //The HTTP status code between 100 and 500 + // The HTTP status code between 100 and 500 status?: integer - //A human-readable explanation specific to this occurrence of the problem + // A human-readable explanation specific to this occurrence of the problem detail?: string - //A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. + // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. id?: string + + // An array of additional error details. errors?: any[] } -``` + - The `title` field is intended for consumption by humans, and therefore **may** change, even within a single version. From 421a3fdb8f470526c99ec8c5d1d9a6b83395ae39 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 10 Jan 2022 23:02:16 -0800 Subject: [PATCH 07/17] Update aip.md --- aip/general/0193/aip.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 24307ece..8c163a8f 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -9,8 +9,9 @@ than being expected to constantly add verbose error handling everywhere. Services **must** clearly distinguish successful responses from error responses by using appropriate HTTP codes: -- Informational responses **must** use HTTP status codes between 100 and 199. -- Successful responses **must** use HTTP status codes between 200 and 399. +- Informational responses issued on a provisional basis while request processing continues **must** use HTTP status codes between 100 and 199. +- Successful responses **must** use HTTP status codes between 200 and 299. +- HTTP status codes between 300 and 399 **must** be used to indicate further action like URL redirection needs to be taken in order to complete the request. - Errors indicating a problem with the user's request **must** use HTTP status codes between 400 and 499. - Errors indicating a problem with the server's handling of an valid request @@ -37,7 +38,8 @@ interface Error { // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. id?: string - // An array of additional error details. errors?: any[] + // A map of metadata returning additional error details that can be used programmatically + metadata?: dict } @@ -45,7 +47,8 @@ interface Error { **may** change, even within a single version. - The `code` field is intended to have code written against it, and therefore **must not** change. Values for this field should be 0-63 characters, and use - only lower-case letters, numbers, and the `-` character. + only lower-case letters, numbers, and the `-` character. These strings should + be comparable using ordinal comparisons. From 2626d2744c728b4db84684c229d7d8ad586a5c88 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 24 Jan 2022 23:27:00 -0800 Subject: [PATCH 08/17] Updating errors AIP per discussion --- aip/general/0193/aip.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 8c163a8f..516f055c 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -24,7 +24,7 @@ Error responses **should** conform to the following interface: ```typescript interface Error { // A machine-readable code indicating the type of error (like `name_too_long`). This value is parseable for programmatic error handling. - code: string; + type: string; // A human readable description of the problem. Should not change from occurrence to occurrence (except for localization). title?: string @@ -36,7 +36,7 @@ interface Error { detail?: string // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. - id?: string + occurenceId?: string // A map of metadata returning additional error details that can be used programmatically metadata?: dict @@ -45,7 +45,7 @@ interface Error { - The `title` field is intended for consumption by humans, and therefore **may** change, even within a single version. -- The `code` field is intended to have code written against it, and therefore +- The `type` field is intended to have code written against it, and therefore **must not** change. Values for this field should be 0-63 characters, and use only lower-case letters, numbers, and the `-` character. These strings should be comparable using ordinal comparisons. @@ -114,7 +114,7 @@ represented with an error object. - For which error codes to retry, see AIP-194. ## Changelog - +- **2022-01-24**: Adopting RFC 7807 with tweaks for the errors AIP. - **2020-09-02**: Refactored errors AIP to be more generic. - **2020-01-22**: Added a reference to the `ErrorInfo` message in gRPC. - **2019-10-14**: Added guidance restricting error message mutability to if From 1c083f9e8be0989fa3a8ddbac9003ec8bbe0bf7c Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Sun, 30 Jan 2022 16:02:11 -0800 Subject: [PATCH 09/17] Clarifying ordinal comparison Co-authored-by: Richard Gibson --- aip/general/0193/aip.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 516f055c..66eb5ad5 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -44,11 +44,11 @@ interface Error { - The `title` field is intended for consumption by humans, and therefore - **may** change, even within a single version. -- The `type` field is intended to have code written against it, and therefore - **must not** change. Values for this field should be 0-63 characters, and use - only lower-case letters, numbers, and the `-` character. These strings should - be comparable using ordinal comparisons. +- The `code` field is intended to support comparison as an opaque sequence of + code points, and therefore **must not** change (even by case folding or + other normalization, e.g. "invalid_auth" and "Invalid_Auth" are distinct). + Values for this field should be 0-63 characters, and use only lower-case + letters, numbers, and the `-` character. From e66cf0d2c95630c5f8d5eb06cba92f5b9619c905 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Fri, 4 Feb 2022 17:34:52 -0800 Subject: [PATCH 10/17] clarifying metadata changes can be breaking --- aip/general/0193/aip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 66eb5ad5..2e7cd290 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -38,7 +38,7 @@ interface Error { // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. occurenceId?: string - // A map of metadata returning additional error details that can be used programmatically + // A map of metadata returning additional error details that can be used programmatically. The schema of metadata should be documented and a change in this schema could mean a breaking change. metadata?: dict } From c499945137b83cf7dcdb8af17a8fbab209e9627f Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Tue, 8 Feb 2022 18:03:09 -0800 Subject: [PATCH 11/17] Minor tweaks per feedback --- aip/general/0193/aip.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 2e7cd290..2763e6ea 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -36,15 +36,16 @@ interface Error { detail?: string // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. - occurenceId?: string + incidentId?: string // A map of metadata returning additional error details that can be used programmatically. The schema of metadata should be documented and a change in this schema could mean a breaking change. metadata?: dict } -- The `title` field is intended for consumption by humans, and therefore -- The `code` field is intended to support comparison as an opaque sequence of +- The `title` field is intended for consumption by humans, and therefore + **may** change, even within a single version. +- The `type` field is intended to support comparison as an opaque sequence of code points, and therefore **must not** change (even by case folding or other normalization, e.g. "invalid_auth" and "Invalid_Auth" are distinct). Values for this field should be 0-63 characters, and use only lower-case @@ -60,7 +61,7 @@ particular API. Additionally, error messages **must not** assume that the user will know anything about its underlying implementation. Error messages **should** be brief but actionable. Any extra information -**should** be provided in a `details` field. If even more information is +**should** be provided in the `metadata` field. If even more information is necessary, the service **should** provide a link where a reader can get more information or ask questions to help resolve the issue. @@ -79,7 +80,7 @@ Below are some examples of good errors and not so good errors: Error messages **must** be in American English. If a localized error message is also required, the service **should** provide the following structure within -its `details`: +its `metadata`: ```typescript interface LocalizedMessage { @@ -89,7 +90,7 @@ interface LocalizedMessage { locale: string; // The localized error message in the above locale. - message: string; + title: string; } ``` From 214fac247f44d59bfb2e9e00c6568f2a533f11c0 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Tue, 8 Feb 2022 18:05:03 -0800 Subject: [PATCH 12/17] Update aip.md --- aip/general/0193/aip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 2763e6ea..fba3e6a2 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -38,7 +38,7 @@ interface Error { // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. incidentId?: string - // A map of metadata returning additional error details that can be used programmatically. The schema of metadata should be documented and a change in this schema could mean a breaking change. + // A map of metadata returning additional error details that can be used programmatically. The schema of metadata should be documented and fixed per `type`. A change in this schema could mean a breaking change. metadata?: dict } From dcc55d86cd412362da7edca2e67b1cb7c15b878a Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 14 Feb 2022 22:14:03 -0800 Subject: [PATCH 13/17] adding examples --- aip/general/0193/aip.md | 47 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index fba3e6a2..53faf7f5 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -41,7 +41,7 @@ interface Error { // A map of metadata returning additional error details that can be used programmatically. The schema of metadata should be documented and fixed per `type`. A change in this schema could mean a breaking change. metadata?: dict } - +``` - The `title` field is intended for consumption by humans, and therefore **may** change, even within a single version. @@ -53,7 +53,7 @@ interface Error { -### Messages +### Error Messages Error messages **should** help a reasonably technical user understand and resolve the issue, and **should not** assume that the user is an expert in the @@ -75,7 +75,48 @@ Below are some examples of good errors and not so good errors: ❌ Bad input ✅ 'ID' must be provided in the input - + + +### Example Error Responses + +Below are examples of how error response could look like: + +1. Book name is too long + +``` +{ + "type": "book_name_too_long", + "title": "Book name must be between 5 and 50 characters", + "status": 400, + "incidentId": "ASAZasGFG2135qsfas2" +} +``` + +2. Invalid input parameters + +``` +{ + "type": "invalid_input_parameters", + "title": "Your request parameters aren't valid", + "status": 400, + "metadata": { + "invalid-params": [ + { + "name": "age", + "reason": "must be a positive integer" + }, + { + "name": "color", + "reason": "must be 'green', 'red' or 'blue'" + } + ] + } +} +``` + + + + ### Localization Error messages **must** be in American English. If a localized error message is From 3cf2ce2411c47a7edb8d0dfd6a1442c28dfc8492 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Mon, 14 Feb 2022 22:16:59 -0800 Subject: [PATCH 14/17] Update aip.md --- aip/general/0193/aip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 53faf7f5..ac701e25 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -48,7 +48,7 @@ interface Error { - The `type` field is intended to support comparison as an opaque sequence of code points, and therefore **must not** change (even by case folding or other normalization, e.g. "invalid_auth" and "Invalid_Auth" are distinct). - Values for this field should be 0-63 characters, and use only lower-case + Values for this field should be 0-63 characters, and use only lower-case or upper case letters, numbers, and the `-` character. From 97eb6471993a4d2597af62a656c52ac66a096b20 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Tue, 15 Mar 2022 10:20:45 -0700 Subject: [PATCH 15/17] Using message instead of title --- aip/general/0193/aip.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index ac701e25..cb23ac37 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -26,15 +26,12 @@ interface Error { // A machine-readable code indicating the type of error (like `name_too_long`). This value is parseable for programmatic error handling. type: string; - // A human readable description of the problem. Should not change from occurrence to occurrence (except for localization). - title?: string + // A human readable description of the problem. Should not change from occurrence to occurrence. + message?: string // The HTTP status code between 100 and 500 status?: integer - // A human-readable explanation specific to this occurrence of the problem - detail?: string - // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. incidentId?: string @@ -43,7 +40,7 @@ interface Error { } ``` -- The `title` field is intended for consumption by humans, and therefore +- The `message` field is intended for consumption by humans, and therefore **may** change, even within a single version. - The `type` field is intended to support comparison as an opaque sequence of code points, and therefore **must not** change (even by case folding or @@ -86,7 +83,7 @@ Below are examples of how error response could look like: ``` { "type": "book_name_too_long", - "title": "Book name must be between 5 and 50 characters", + "message": "Book name must be between 5 and 50 characters", "status": 400, "incidentId": "ASAZasGFG2135qsfas2" } @@ -97,7 +94,7 @@ Below are examples of how error response could look like: ``` { "type": "invalid_input_parameters", - "title": "Your request parameters aren't valid", + "message": "Your request parameters aren't valid", "status": 400, "metadata": { "invalid-params": [ @@ -131,7 +128,7 @@ interface LocalizedMessage { locale: string; // The localized error message in the above locale. - title: string; + message: string; } ``` From 1de2d49eaa920369df68f7c726107effc026cf47 Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Wed, 7 Sep 2022 10:37:43 -0700 Subject: [PATCH 16/17] Update aip.md --- aip/general/0193/aip.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index cb23ac37..2f53d5d7 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -26,7 +26,7 @@ interface Error { // A machine-readable code indicating the type of error (like `name_too_long`). This value is parseable for programmatic error handling. type: string; - // A human readable description of the problem. Should not change from occurrence to occurrence. + // A human-readable description of the problem. Messages are likely to be logged in plain text and should not include information about a specific occurrence. Information about specific occurrences should be part of `metadata`. message?: string // The HTTP status code between 100 and 500 @@ -70,9 +70,6 @@ Below are some examples of good errors and not so good errors: ❌ Access is denied ✅ Only admin users have access to this resource. - ❌ Bad input - ✅ 'ID' must be provided in the input - ### Example Error Responses From 10c62b6205f20120f04da9fe169af096a00b04ff Mon Sep 17 00:00:00 2001 From: Saurabh Sahni Date: Wed, 21 Sep 2022 10:23:02 -0700 Subject: [PATCH 17/17] Update aip.md --- aip/general/0193/aip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aip/general/0193/aip.md b/aip/general/0193/aip.md index 2f53d5d7..bdbf297d 100644 --- a/aip/general/0193/aip.md +++ b/aip/general/0193/aip.md @@ -35,7 +35,7 @@ interface Error { // A unique identifier that identifies the specific occurrence of the problem. Can be provided to the API owner for debugging purposes. incidentId?: string - // A map of metadata returning additional error details that can be used programmatically. The schema of metadata should be documented and fixed per `type`. A change in this schema could mean a breaking change. + // A map of metadata returning additional error details that can be used programmatically. The schema of metadata should be documented and fixed per `type`. Schema of `metadata` is part of your API. Within a single version, breaking changes to `metadata` structure should not be performed; consider limiting depth of nested objects. metadata?: dict } ```