@@ -51,12 +51,12 @@ developers to understand the problem and is more detailed than
5151
5252Messages ** should** use simple descriptive language that is easy to understand
5353(without technical jargon) to clearly state the problem that results in an
54- error.
54+ error, and offer an actionable resolution to it .
5555
56- For pre-existing (brownfield) APIs which have returned errors without
57- additional details in the past , the value of ` message ` must remain the same
58- for any given error, as developers have previously had no option but to use
59- this for error handling. For more information, see
56+ For pre-existing (brownfield) APIs which have previously returned errors
57+ without machine-readable identifiers , the value of ` message ` ** must**
58+ remain the same for any given error, as developers have previously had no
59+ option but to use this for error handling. For more information, see
6060[ Changing Error Messages] ( #changing-error-messages ) .
6161
6262### Status.code
@@ -96,121 +96,81 @@ The following sections describe the most common standard detail payloads.
9696
9797#### ErrorInfo
9898
99- The [ ` ErrorInfo ` ] [ ErrorInfo ] message is the required way to send a
100- machine-readable identifier. All error responses ** must** include an
101- ` ErrorInfo ` payload in ` details ` . Variable information ** should** be
99+ The [ ` ErrorInfo ` ] [ ErrorInfo ] message is the primary way to send a
100+ machine-readable identifier. Contextual information ** should** be
102101included in ` metadata ` in ` ErrorInfo ` and ** must** be included if it
103102appears within an error message.
104103
105- When introducing an error that represents a failure scenario that did
106- not previously occur for the service, the payload ** must ** include
107- ` ErrorInfo ` and any variables found in dynamic segments of the error
108- message ** must ** be present in ` ErrorInfo.metadata ` (See [ Dynamic
109- variables ] ( #dynamic-variables ) .)
104+ The ` reason ` field is a short snake_case description of the cause of the
105+ error. Error reasons are unique within a particular domain of errors.
106+ The reason ** must ** be at most 63 characters and match a regular expression of
107+ ` [A-Z][A-Z0-9_]+[A-Z0-9] ` . (This is UPPER_SNAKE_CASE, without leading
108+ or trailing underscores, and without leading digits .)
110109
111- ** Note: ** ` ErrorInfo ` represents a special case. There ** must ** be
112- exactly one ` ErrorInfo ` . It is required .
110+ The reason should be terse, but meaningful enough for a human reader to
111+ understand what the reason refers to .
113112
114- [ ErrorInfo Payload ] [ ErrorInfo ]
113+ Good examples:
115114
116- Details of this object are summarized in the following fields, field
117- descriptions, and examples:
115+ - ` CPU_AVAILABILITY `
116+ - ` NO_STOCK `
117+ - ` CHECKED_OUT `
118+ - ` AVAILABILITY_ERROR `
118119
119- - ` reason string `
120- - A short snake_case description of why the error occurred. Error
121- reasons are unique within a particular domain of errors. The error
122- reason ** must** do the following:
123- - Be at most 63 characters and match a regular expression of
124- ` /[A-Z][A-Z0-9_]+[A-Z0-9]/ ` , which represents UPPER_SNAKE_CASE.
125- - Be meaningful enough for a human reader to understand what the
126- reason refers to.
127- - Be unique and consumable by machine actors for automation.
128- - * Example* : CPU_AVAILABILITY<br >
129- Distill your error message into its simplest form. For example, the
130- ` reason string ` could be one of the following text examples in
131- UPPER_SNAKE_CASE: ` UNAVAILABLE ` , ` NO_STOCK ` , ` CHECKED_OUT ` ,
132- ` AVAILABILITY_ERROR ` , if your error message is,
133-
134- > The Book, "The Great Gatsby", is unavailable at the Library,
135- > "Garfield East". It is expected to be available again on 2199-05-13.
136-
137- - In contrast, using either of the following reasons is not
138- recommended: ` THE_BOOK_YOU_WANT_IS_NOT_AVAILABLE ` , ` ERROR ` . And,
139- using either of the following reasons breaches the required
140- formatting and is not allowed: ` librariesAreGreat ` , ` noBooks ` .
141-
142- - ` domain string `
143- - The logical grouping to which the ` reason ` belongs. The error domain
144- is typically the registered service name of the tool or product that
145- generated the error. The domain must be a globally unique value.
146- - * Example* :<br >` pubsub.googleapis.com `
147-
148- - ` metadata map `
149- - Additional structured details about this error, which ** should**
150- provide important context for customers to identify resolution
151- steps. Keys ** should** match ` /[a-z][a-zA-Z0-9-_]+/ ` , and be
152- limited to 64 characters in length. When identifying the current
153- value of an exceeded limit, the units ** should** be contained in the
154- key, not the value.
155- - * Example* :
156- ```
157- "vmType": "e2-medium",
158- "attachment": "local-ssd=3,nvidia-t4=2",
159- "zone": "us-east1-a"
160- ```
161- - For guidance on using the metadata map, see [Dynamic
162- Variables](#dynamic-variables).
120+ Bad examples:
163121
164- ##### Dynamic variables
122+ - ` THE_BOOK_YOU_WANT_IS_NOT_AVAILABLE ` (overly verbose)
123+ - ` ERROR ` (too general)
165124
166- The best, actionable error messages include dynamic segments. These
167- variable parts of the message are specific to a particular request.
168- Without such context, it is unlikely that the message will be fully
169- actionable by the user.
125+ The ` domain ` field is the logical grouping to which the ` reason ` belongs.
126+ The domain ** must** be a globally unique value, and is typically the name of the service
127+ that generated the error, e.g. ` pubsub.googleapis.com ` .
170128
171- This practice is critical so that machine actors do not need to rely on
172- `LocalizedMessage.message`, which is subject to change and is not part
173- of the API contract.
129+ The (reason, domain) pair form a machine-readable way of identifying a particular error.
130+ Services ** must** use the same (reason, domain) pair for the same error, and
131+ ** must not** use the same (reason, domain) pair for logically different errors.
132+ The decision about whether two errors are "the same" or not is not always clear, but
133+ ** should** generally be considered in terms of the expected action a client might take
134+ to resolve them.
174135
175- Consider the following example:
136+ The ` metadata ` field is a map of key/value pairs providing additional
137+ dynamic information as context. Each key within ` metadata ` ** must** be at most
138+ 64 characters long, and conform to the regular expression ` [a-z][a-zA-Z0-9-_]+ ` .
176139
177- > The Book, "The Great Gatsby", is unavailable at the Library, "Garfield
178- > East". It is expected to be available again on 2199-05-13.
140+ Any request-specific information which contributes to the ` Status.message ` or
141+ ` LocalizedMessage.message ` messages ** must** be represented within ` metadata ` .
142+ This practice is critical so that machine actors do not need to parse error
143+ messages to extract information.
179144
180- The preceding error message is made actionable by the context, both
181- originating from the request, the title of the Book, the name of the
182- Library, and by the information that is known only by the service, that
183- is, the expected return date of the Book.
145+ For example consider the following message:
184146
185- All dynamic variables found in error messages **must** also be present
186- in the `map<string, string>`, `ErrorInfo.metadata` (found on the
187- *required* `ErrorInfo`). For example, the `metadata` map for the sample
188- error message above will include *at least* the following key/value
189- pairs:
147+ > An & lt ; e2-medium & gt ; VM instance with & lt ; local-ssd=3,nvidia-t4=2 & gt ; is currently unavailable
148+ > in the & lt ; us-east1-a & gt ; zone. Consider trying your request in the & lt ; us-central1-f,us-central1-c & gt ;
149+ > zone(s), which currently has/have capacity to accommodate your request. Alternatively,
150+ > you can try your request again with a different VM hardware configuration
151+ > or at a later time. For more information, see the troubleshooting documentation.
190152
191- ```
192- bookTitle: "The Great Gatsby"
193- library: "Garfield East"
194- expectedReturnDate: "2199-05-13"
195- ```
153+ The ` ErrorInfo.metadata ` map for the same error could be:
196154
197- The following example shows an additional example of a metadata map for
198- information about virtual machines:
155+ - ` "zone": "us-east1-a" `
156+ - ` "vmType": "e2-medium" `
157+ - ` "attachment": "local-ssd=3,nvidia-t4=2" `
158+ - ` "zonesWithCapacity": "us-central1-f,us-central1-c" `
199159
200- ```
201- vmType: "<VM-TYPE >",
202- attachment: "<ATTACHMENT >"
203- zone: "<ZONE >"
204- ```
160+ Additional contextual information that does not appear in an error message
161+ ** may** also be included in ` metadata ` to allow programmatic use by the client.
162+
163+ The metadata included for any given (reason,domain) pair can evolve over time:
164+
165+ - New keys ** may** be included
166+ - All keys that have been included ** must** continue to be included (but may have empty values)
205167
206- Dynamic variables that do not appear in an error message **may** also be
207- included in `metadata` to provide additional information to the client
208- to be used programmatically.
168+ In other words, once a user has observed a given key for a (reason, domain) pair, the
169+ service ** must** allow them to rely on it continuing to be present in the future.
209170
210- Once present in `metadata`, keys **must** continue to be included in the
211- map for the error payload to be backwards compatible, even if the value
212- for a particular key is empty. Keys **must** be expressed as lower
213- camel-case.
171+ The set of keys provided in each (reason, domain) pair is independent from other pairs,
172+ but services ** should** aim for consistent key naming. For example, two error reasons
173+ within the same domain should not use metadata keys of ` vmType ` and ` virtualMachineType ` .
214174
215175#### Localization
216176
0 commit comments