opengeospatial / ogcapi-common

OGC API - Common provides those elements shared by most or all of the OGC API standards to ensure consistency across the family.
https://ogcapi.ogc.org/common
Other
45 stars 14 forks source link

11.3 consider standard exception template #73

Closed fterpstra closed 3 years ago

fterpstra commented 4 years ago

Good default formats for exceptions is [rfc7807]. A JSON-representation of an error is formulated like the following object:

{ "type": "URI: https://content.omgevingswet.overheid.nl/id/[/{categorie}]/{fout}", "title": "Hier staat wat er is misgegaan", "status": 401, "detail": "Meer details over de fout staan hier", "instance": "urn:uuid:ebd2e7f0-1b27-11e8-accf-0ed5f89f718b" // The error instance
}

cmheazel commented 4 years ago

A JSON Schema for exceptions is provided here but does not appear to be referenced in the standard. Is this schema acceptable?

pomakis commented 4 years ago

I think it's essential that "OGC API - Common" dictate a JSON schema for exceptions (4xx and 5xx alike). There's nothing more frustrating than a user getting a pop-up dialog that says nothing but "an HTTP 400 error has occurred" or "an HTTP 500 error has occurred". There aught to be a way for a client application to sniff out a human-readable description of the exception so that it can present it to the user appropriately. In many cases the user still might not be able to actually do anything about it, but in some cases they might. At the very least they'll have something more specific to pass on to the server administrator.

I don't think an exceptionCode (as per OWS Common ExceptionReports) is necessary, but I wouldn't strongly object if others feel that it is.

One thing that I would like to see in an exception schema, however, is the ability to report a multi-level description of the exception. For example:

"An internal server error has occurred (reference ID: 47346734)"
(because...)
"Execution reached a section of code that is not yet implemented"

or

"Illegal value specified for parameter 'subset'"
(because...)
"Coordinate system does not have a dimension called 'Lon'"

It's certainly worth exploring RFC 8707. It doesn't provide the ability to report a multi-level description of the exception, but "OGC API - Common" could add that as an extension if others agree that it would be nice to have.

ghobona commented 4 years ago

This came up again during the July 2020 sprint. The sprint participants noted that the issue is not yet OBE.

The suggestion was that this should be a stack-based Exception report.

cmheazel commented 3 years ago

@ghobona where can I find the schema for a "stac-based exception report"? I don't see such a creature on the Stac GitHub.

ghobona commented 3 years ago

@cmheazel I cannot find it either. Perhaps @pomakis @joanma747 @jerstlouis might remember the details of the suggestion from the sprint participants.

jerstlouis commented 3 years ago

@cmheazel "stack", not STAC :)

@pomakis made a suggestion here

cmheazel commented 3 years ago

JSON and YAML schemas have been updated as suggested.

pomakis commented 3 years ago

I have upgraded CubeWerx's test implementation at

https://test.cubewerx.com/cubewerx/cubeserv/demo/ogcapi/Daraa

to report exceptions using this schema.

cportele commented 3 years ago

If Common makes a recommendation for a JSON encoding for exceptions, the recommendation should at least include RFC 7807 in the recommendation as an option.

joanma747 commented 3 years ago

RFC 7807 suggest this:

o "type" (string) Mandatory - A URI reference [RFC3986] that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be "about:blank".

o "title" (string) Optional - A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).

o "status" (number) Optional - The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.

o "detail" (string) Optional - A human-readable explanation specific to this occurrence of the problem.

o "instance" (string) Optional - A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.

We could use this one that is very similar to what is suggested in https://github.com/opengeospatial/ogcapi-common/issues/180

Differences are:

Note that if we make this a requirement, the actual requirement says: The exception report response should be an object and have a member called "type" that is a URI.

RESOLUTION: The OWS Common telco today agrees on making this a recommendation in the "exceptions" section. This implicitly supersedes the suggestions in https://github.com/opengeospatial/ogcapi-common/issues/180

pomakis commented 3 years ago

My only concern with adopting an exception report that's compliant with RFC 7807 is that we'd then have the additional requirement of defining a set of "type" URLs. If we take this route, I'd strongly recommend defining just one for use across all OGC APIs, indicating merely that it's an OGC API exception report. Otherwise we're in for years of mess trying to define and synchronize what the different "type" URLs should be across the different OGC API specifications.

I'm also not sure of "title". The "it SHOULD NOT change from occurrence to occurrence of the problem" part puzzles me. It kind of implies that it shouldn't be free-form and that somehow the OGC API specifications should play a role in defining its values. This could further add unnecessary complication if we're not careful.

cmheazel commented 3 years ago

Changes applied to API-Common Part 1 including: 1) Creation of a JSON schema for RFC 7807 (there is no standard schema) - this includes the "details" element from the previous schema. 2) Added recommendation to use RFC 7807 to section 8.1.2 3) added RFC 7807 to the normative references 4) added media types for 7807 reports to section 11 (includes both JSON and XML) 5) Created example JSON Problem Details report 6) Added recommendation to use 7807 to JSON conformance class including a link to the schema and example.

cmheazel commented 3 years ago

@pomakis I think we can handle it.

The "type" URLs will point to an OGC registry. So there will be minimum conflict with other organizations.

As for the types of exception, we should NOT register any exception type which does not have one or more corresponding requirements specifying the information to be returned. This rule greatly reduces the number of types that need to be registered.

Registration would also assure that the same error condition is not reported in different ways by different OGC Web API standards. This is goodness. Particularly since our modular approach can lead to deployed APIs which mix modules from different standards.

Finally, this type of coordination is why the OGC Naming Authority exists.

cportele commented 3 years ago

It is ok, if there is no value for "type". Then "about:blank" is assumed.

I think we can discuss at some point, if there is value in creating and maintaining a register of OGC API errors beyond the HTTP status codes, but it should not be required to use them. When we discussed this in Features, we decided to stick to HTTP status codes for now and not try to standardize anything beyond that. The attempts with OGC error types did not work well in the WxS standards, in my opinion.

Here is an example of the RFC 7808 content that ldproxy currently returns:

Request: https://demo.ldproxy.net/daraa/collections/CulturePnt/items?f=json&foo=bar

Response:

HTTP/1.1 400 Bad Request
Content-Length: 286
Content-Type: application/problem+json
Date: Tue, 19 Jan 2021 08:18:51 GMT
Vary: Accept

{
  "status" : 400,
  "title" : "Bad Request",
  "detail" : "The following query parameters are rejected: foo. Valid parameters for this request are: bbox, bbox-crs, crs, datetime, f, filter, filter-lang, limit, maxAllowableOffset, offset, properties, skipGeometry, F_CODE, ZI037_REL"
}
pomakis commented 3 years ago

If we can keep things simple like that and use the implicit default type of "about:blank" for the standard OGC API exception responses, then I'm fine with adopting RFC 7807.

Note, however, that the current ExceptionExample.json example that was recently added to OGC API - Common Part 1 doesn't take this approach. It illustrates a type that's specific to parameter-validation errors, which implies that a type URL for this specific type of error be defined by OGC API - Common Part 1 and added to an OGC registry. Like @cportele, I saw no value in the OWS exception codes defined by OWS Common (OGC 06-121r3, etc.), and prefer to avoid getting the OGC API tangled up with similar unnecessary complications.

pomakis commented 3 years ago

I do definitely see value in defining an extra field for optionally communicating extra levels of detail. Such a field needs to be defined by OGC API - Common Part 1, but isn't yet. In a comment in issue 180, I suggested the following schema:

"details": {
  "type": "array",
  "items": {
    "type": "object",
    "required": [ "description" ],
    "properties": {
      "description": {
        "type": "string"
      }
    }
  }
}

(I removed "minItems" here because there's no need to disallow an empty array.)

Perhaps the field should be called "extendedDetails", "extended_details", "moreDetails" or "more_details" instead, to indicate that it augments (without duplication) the "detail" field. (Sorry, kebab case isn't allowed by RFC 7807.)

The current ExceptionExample.json shows such a field. However, I'm not fond of the specific example. I think the field should be defined to provide a stack-based or drill-down series of descriptions for the exception being described (as I illustrated in an earlier comment). Whereas the current ExceptionExample.json example is essentially describing two separate exceptions (a bad value for the "age" parameter and a bad value for the "color" parameter). While it may be tempting to cater to allowing an exception report to describe multiple exceptions at once like this, in practice it's usually not very useful. In this particular case, most server implementations will throw the exception after the first parameter-validation error rather than continuing to validate the other parameters. (In some cases, where the interpretation of one parameter depends on the value of another, continuing on after the first parameter-validation error is actually impossible.)

In summary, I think ExceptionExample.json should be changed to:

{
  "title" : "Bad Request",
  "status": 400,
  "detail": "the 'age' parameter does not validate",
  "instance": "urn:uuid:ebd2e7f0-1b27-11e8-accf-0ed5f89f718b",
  "details": [
    { "description": "must be a positive integer" }
  ]
}

(Note the implicit "about:blank" type, as per my previous comment.)

pomakis commented 3 years ago

Sorry for spamming this issue, but the ideas keep rolling in as I experiment with an implementation.

I wrote:

Perhaps the field should be called "extendedDetails", "extended_details", "moreDetails" or "more_details" instead, to indicate that it augments (without duplication) the "detail" field. (Sorry, kebab case isn't allowed by RFC 7807.)

I'm now thinking that since the elements of the OGC-API-defined "details" field are meant to be extensible to allow for extra information to be passed, then perhaps it should represent the full stack of exception messages (with the first detail in the stack possibly duplicating the text of the RFC7807-standard "detail" field). If a client parser is equipped to recognize the OGC-API-defined "details" field, it could choose to ignore the "detail" field and parse everything it needs out of the "details" field. Otherwise it would parse the "detail" field as usual.

In this case, ExceptionExample.json should be:

{
  "title" : "Bad Request",
  "status": 400,
  "detail": "the 'age' parameter does not validate",
  "details": [
    { "description": "the 'age' parameter does not validate" },
    { "description": "must be a positive integer" }
  ],
  "instance": "urn:uuid:ebd2e7f0-1b27-11e8-accf-0ed5f89f718b"
}
cportele commented 3 years ago

By the way, IETF is starting a process to create a successor to RFC 7807. The main driver is to support "reporting of multiple errors of the same problem type in an error response"; for example, multiple schema validation errors in the content.

This might help with the issues discussed here and it would also be an opportunity to try to convince the HTTP API WG to make other changes that we consider important (not just for "our" APIs), if there are any.

Here is the repo: https://github.com/ietf-wg-httpapi/rfc7807bis. Discussions will take place mainly on the HTTP API WG mailing list.

cmheazel commented 3 years ago

February 1 - move to cross-SWG
Modify schema to align with current RFC 7807. Leave open pending IETF results. This issue does not have to be resolved for the initial release.

cmheazel commented 3 years ago

API-Common Part 1 - the exception schema has been updated to conform with RFC 7807. This schema will be updated to conform with the revised version of RFC 7807 once it is finalized.