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