Skip to content

Commit dc20558

Browse files
authored
Add more failure attributes and specific errors (#21)
1. Add `cause` and `stackTrace` attributes to `Failure` 2. Document `HandlerError` 3. Document `OperationError` 4. Add the `CONFLICT` handler error type 5. Add the `REQUEST_TIMEOUT` handler error type 6. Remove mentions of response codes that are covered by handler error types 7. Deprecate the `Nexus-Request-Retryable` and `Nexus-Operation-State` headers since this information should be present in the response body.
1 parent 13c4851 commit dc20558

File tree

1 file changed

+77
-30
lines changed

1 file changed

+77
-30
lines changed

SPEC.md

Lines changed: 77 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ properties:
4343
type: string
4444
description: A simple text message.
4545

46+
stackTrace:
47+
type: string
48+
description: An optional stack trace that may be emitted in languages that support it.
49+
4650
metadata:
4751
type: object
4852
additionalProperties:
@@ -55,6 +59,10 @@ properties:
5559
properties:
5660
description: |
5761
Additional JSON-serializable structured data.
62+
63+
cause:
64+
# An optional nested failure structure.
65+
$ref: '#'
5866
```
5967
6068
### OperationInfo
@@ -141,17 +149,9 @@ The body may contain arbitrary data. Headers should specify content type and enc
141149
**Headers**:
142150

143151
- `Content-Type: application/json`
144-
- `Nexus-Operation-State: failed | canceled`
145-
146-
**Body**: A JSON-serialized [`Failure`](#failure) object.
152+
- `Nexus-Operation-State: failed | canceled` (DEPRECATED)
147153

148-
- `409 Conflict`: Operation was already started with a different request ID.
149-
150-
**Headers**:
151-
152-
- `Content-Type: application/json`
153-
154-
**Body**: A JSON-serialized [`Failure`](#failure) object.
154+
**Body**: A JSON-serialized [`Failure`](#failure) object representing an [`OperationError`](#operation-error).
155155

156156
### Cancel Operation
157157

@@ -178,33 +178,80 @@ The operation token received as a response to the Start Operation method must be
178178

179179
**Body**: Empty.
180180

181-
- `404 Not Found`: Operation token not recognized or references deleted.
181+
## Predefined Failure Types
182182

183-
**Headers**:
183+
### `OperationError`
184184

185-
- `Content-Type: application/json`
185+
An Operation Error represents a failed or canceled operation outcome. It may be returned responses to `StartOperation`
186+
requests, and in the body of async completion requests.
187+
188+
Operation Error [`Failure`](#failure) representation is as follows:
186189

187-
**Body**: A JSON serialized [`Failure`](#failure) object.
190+
```json
191+
{
192+
"metadata": {
193+
"type": "nexus.OperationError",
194+
},
195+
"message": "<Optional error message>",
196+
"stackTrace": "<Optional stack trace>",
197+
"cause": { /* <Optional cause> */ },
198+
"details": {
199+
"state": "canceled | failed",
200+
// Aribtrary details may be added here as needed.
201+
},
202+
}
203+
```
204+
205+
### `HandlerError`
206+
207+
A HandlerError represents errors while handling a request. They include an error type as defined
208+
[below](#predefined-handler-errors). Each error type has predefined, overridable, retry semantics. Handler Errors can be
209+
returned responses to any of the methods defined above as well as completion callbacks.
210+
211+
Handler Error [`Failure`](#failure) representation is as follows:
212+
213+
```json
214+
{
215+
"metadata": {
216+
"type": "nexus.HandlerError",
217+
},
218+
"message": "<Optional error message>",
219+
"stackTrace": "<Optional stack trace>",
220+
"cause": { /* <Optional cause> */ },
221+
"details": {
222+
"type": "<predefined error type (e.g. INTERNAL)",
223+
// "retryableOverride": Optional boolean.
224+
// Aribtrary details may be added here as needed.
225+
},
226+
}
227+
```
188228

189-
## Predefined Handler Errors
229+
### Predefined Handler Errors
190230

191231
For compatiblity of this HTTP spec with future transports, when a handler fails a request, it **should** use one of the
192232
following predefined error codes.
193233

194-
| Name | Status Code | Description |
195-
| -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
196-
| `BAD_REQUEST` | 400 | The handler cannot or will not process the request due to an apparent client error. Clients should not retry this request unless advised otherwise. |
197-
| `UNAUTHENTICATED` | 401 | The client did not supply valid authentication credentials for this request. Clients should not retry this request unless advised otherwise. |
198-
| | | |
199-
| `UNAUTHORIZED` | 403 | The caller does not have permission to execute the specified operation. Clients should not retry this request unless advised otherwise. |
200-
| | | |
201-
| `NOT_FOUND` | 404 | The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible but not advised. |
202-
| | | |
203-
| `RESOURCE_EXHAUSTED` | 429 | Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. Subsequent requests by the client are permissible. |
204-
| `INTERNAL` | 500 | An internal error occured. Subsequent requests by the client are permissible. |
205-
| `NOT_IMPLEMENTED` | 501 | The handler either does not recognize the request method, or it lacks the ability to fulfill the request. Clients should not retry this request unless advised otherwise. |
206-
| `UNAVAILABLE` | 503 | The service is currently unavailable. Subsequent requests by the client are permissible. |
207-
| `UPSTREAM_TIMEOUT` | 520 | Used by gateways to report that a request to an upstream handler has timed out. Subsequent requests by the client are permissible. |
234+
| Name | Status Code | Description |
235+
| -------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
236+
| `BAD_REQUEST` | 400 | The handler cannot or will not process the request due to an apparent client error. Clients should not retry this request unless advised otherwise. |
237+
| `UNAUTHENTICATED` | 401 | The client did not supply valid authentication credentials for this request. Clients should not retry this request unless advised otherwise. |
238+
| `UNAUTHORIZED` | 403 | The caller does not have permission to execute the specified operation. Clients should not retry this request unless advised otherwise. |
239+
| `NOT_FOUND` | 404 | The requested resource could not be found but may be available in the future. Subsequent requests by the client are permissible but not advised. |
240+
| `REQUEST_TIMEOUT` | 408 | Returned by the server to when it has given up handling a request. The may occur by enforcing a client provided `Request-Timeout` or for any arbitrary reason such as enforcing some configurable limit. Subsequent requests by the client are permissible. |
241+
| `CONFLICT` | 409 | The request could not be made due to a conflict. The may happen when trying to create an operation that has already been started. Clients should not retry this request unless advised otherwise. |
242+
| `RESOURCE_EXHAUSTED` | 429 | Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. Subsequent requests by the client are permissible. |
243+
| `INTERNAL` | 500 | An internal error occured. Subsequent requests by the client are permissible. |
244+
| `NOT_IMPLEMENTED` | 501 | The handler either does not recognize the request method, or it lacks the ability to fulfill the request. Clients should not retry this request unless advised otherwise. |
245+
| `UNAVAILABLE` | 503 | The service is currently unavailable. Subsequent requests by the client are permissible. |
246+
| `UPSTREAM_TIMEOUT` | 520 | Used by gateways to report that a request to an upstream handler has timed out. Subsequent requests by the client are permissible. |
247+
248+
Client implementations should try to rehydrate a `HandlerError` from the serialized `Failure` object in the response
249+
body whenever a request fails with one of the status codes listed below. If the handler error type in the `Failure`
250+
object details doesn't match the response status code, the `Failure` object takes precendence.
251+
252+
If the serialized `Failure` does not represent a `HandlerError`, clients should construct a wrapper `HandlerError`,
253+
setting the response `Failure` as the `cause` (if available) translating the response status code to the `HandlerError`
254+
type and status text to the message.
208255

209256
## General Purpose Headers
210257

@@ -220,7 +267,7 @@ Links must contain a `type` parameter that expresses how they should be parsed.
220267

221268
**Example**: `Nexus-Link: <myscheme://somepath?k=v>; type="com.example.MyResource"`
222269

223-
### `Nexus-Request-Retryable`
270+
### `Nexus-Request-Retryable` (DEPRECATED)
224271

225272
Handlers may specify the `Nexus-Request-Retryable` header with a value of `true` or `false` to explicitly instruct a
226273
caller whether or not to retry a request. Unless specified, retry behavior is determined by the

0 commit comments

Comments
 (0)