-
Notifications
You must be signed in to change notification settings - Fork 84
describe correctly-formatted error responses #1438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we limit it to new APIs? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,63 +1,13 @@ | ||
| # A modest proposal for error formats in FOLIO | ||
| # Error responses in FOLIO | ||
|
|
||
| > **NOTE.** This is a non-normative proposal, not at this stage a description of how things are actually done. | ||
| > Thu 12 Jan 16:59:27 GMT 2017 | ||
|
|
||
| In almost all cases, when a server-side module needs to report an error to the client that invoked it, the HTTP status code conveys enough machine-readable information for the client software to decide what do (abort, retry, fail, ignore, etc.) But in a small number of cases, more expressive diagnostics are of use. | ||
|
|
||
| ## Example | ||
|
|
||
| For example, one could imagine a client submitting an edit which fails validation on the server side: then the response could contain a list of validation-failure objects, each containing a fieldName, maybe the associated fieldValue that failed, and an explanation of why it was rejected: | ||
| APIs that supply JSON in "success" (2xx) responses with a content-type header of "application/json" must likewise supply JSON in "error" (4xx, 5xx) responses with a content-type header of "application/json". | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't see a need for this limitation. An API that returns 204 (= non content) on success should return a JSON with error details on failure. An API that returns a CSV text on success should return a JSON with error details on failure. |
||
|
|
||
| The response object must contain either a top-level property `message` or a top-level property `errors` that contains an array of objects with `message` properties. That is, a response object must be shaped like this: | ||
| ``` | ||
| 400 Bad Request | ||
| Content-Type: application/json | ||
|
|
||
| { | ||
| "errorCode": "ValidationFailed", | ||
| "message": "Some submitted fields contained invalid values", | ||
| "details": [ | ||
| { | ||
| "fieldName": "phone", | ||
| "fieldValue": "01279 504 468", | ||
| "explanation": "value must not contain spaces" | ||
| }, | ||
| { | ||
| "fieldName": "email", | ||
| "fieldValue": "demon.co.uk!n4!mirk", | ||
| "explanation": "UUCP-style mail addresses are not supported" | ||
| } | ||
| ] | ||
| } | ||
| { message: "", ...} | ||
| ``` | ||
|
|
||
| A clever UI could use this to annotate its edit page and guide the user. | ||
|
|
||
| ## Proposal | ||
|
|
||
| We suggest that FOLIO modules may return errors to clients in either | ||
| of two formats: a simple plain-text message, or a structured JSON object. | ||
|
|
||
| * HTTP status is king -- always convey information via that first. | ||
| * When the status is 4xx or 5xx, the response body contains additional error information. | ||
| * Additional error information may be `text/plain` or `application/json`. | ||
| * When it is `application/json`, it must always be an object containing an `errorCode` key whose value is an opaque code taken from a vocabulary that we will establish (possibly namespaced by module). | ||
| * The object must also contain a `message` key whose value is a human-readable string like the one that would have been used if the content had been `text/plain`. | ||
| * Additional keys within the JSON structure, if any, are dependent on the `errorCode`: documentation of each code includes a specification of what additional fields are included, and their types and meaning. | ||
|
|
||
| ## Consequences | ||
|
|
||
| If this convention is adopted, then any back-end module can easily upgrade a given error report from the basic text/plain form to a superset JSON error object as and when needed. | ||
|
|
||
| When receiving an error response, it is the responsibility of the client to check the content-type and be prepared to handle either plain text or JSON. If the client runs into a JSON error that it doesn't know how to handle, then at least it knows to use the `message` element of the object as the error-message. More sophisticated handling can be added on the client side as and when. | ||
|
|
||
| It might make sense if there are error codes not covered by HTTP but needed across a variety of modules to provide a set of standard error codes but require that any codes not on the list, use a module-based namespace encoding. | ||
|
|
||
| Since we have no immediate need for structured error information, there is little gain _now_ from adopting this approach. But it will be a big win down the line when we decide we need more expressive power in diagnostics. The ugrade path is very painless, as individual errors on the server side can be upgraded as and when; and no such change will require a corresponding UI change, the additional information will just be there for the UI to use when it's ready. | ||
|
|
||
| So upgrading the format of an error reported by service doesn't break anything. | ||
|
|
||
| ## Special case: multiple errors | ||
|
|
||
| If for some reason a service wants to report multiple unrelated errors in a single response, it could do so using the error-code `MultipleErrors` and providing a `details` array each of whose elements is an error object like the top-level one. (I am not sure there is really a need for this, but it's worth pointing out that this simple proposal does cover that complex case.) | ||
|
|
||
| or like this: | ||
| ``` | ||
| { errors: [{ message: "", ...}, ...]} | ||
| ``` | ||
| These are the only required properties. Additional properties at any level are optional. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be worded as a recommendation? We don't have an approved decision record yet.