Closed staplegun closed 6 years ago
Possible bad requests and their current status:
ID | Bad... | Example | Response | Status |
---|---|---|---|---|
1 | Endpoint stub | /bad |
404 no body error message |
OK, but should add message |
2 | Endpoint with path | /bad/more |
404 with body error message |
OK |
3 | Flag | /object?bad |
Server error | Needs fixing |
4 | Parameter empty | /object?bad= |
404 with body results message |
Should return error |
5 | Parameter value | /object?bad=99 |
404 with body error message |
OK |
Requests 3 and 4 are incorrect and need fixing. Request 1 could add a message to be more helpful to developers.
<p:choose>
...
<p:when test=" matches($relative-uri, '[^/]+/[^?]+') or contains($relative-uri, '?')">
<!-- the "format" parameter can be used to specify a content type (overriding Accept header) -->
<p:variable name="format" select="/c:param-set/c:param[@name='format']/@value"/>
<!-- Translate the API request into a request to Solr -->
<p:xslt>
<p:with-param name="relative-uri" select="$relative-uri"/>
<p:input port="stylesheet">
<p:document href="../xslt/api-request-to-solr-request.xsl"/>
</p:input>
</p:xslt>
<!-- Make the HTTP request to Solr, extract response data from Solr's response and reformat it as an API response -->
<p:http-request/>
<nma:format-result>
<p:with-option name="accept" select="$accept"/>
<p:with-option name="format" select="$format"/>
<p:with-option name="relative-uri" select="$relative-uri"/>
</nma:format-result>
</p:when>
<!-- unknown request URI -->
<p:otherwise>
<z:not-found/>
</p:otherwise>
</p:choose>
This seems doable: move the p:when
above down into the XSLT, and drop the p:otherwise
. That XSLT would therefore need to handle bad requests that it can't translate into Solr requests. At the moment, it returns a c:request
document always (that gets passed to the p:http-request
step that follows it). Instead, in the case of syntactically invalid request URIs, it could directly produce a "Solr-response"-type document saying "error in URI", and we could wrap the p:http-request
step in a p:choose
/p:when
so it only happens if the document is in fact an http request specification. Then the nma-format-result
sub-pipeline could format the result document (which would have come either from Solr or direct from the request-parser).
I now have a try/catch
around the parsing of URI parameters. If the parsing succeeds, then the parsed parameters are converted by an XSLT into an http request to Solr, and the request is executed, with the result (including any errors) formatted as either JSON-API or JSON-LD by the solr-xml-to-json.xsl
stylesheet. If the URI parameter parsing fails (e.g. on /object?foo
), an error message is produced in Solr format (i.e. as if it had been produced by Solr), and that error response is then converted to the appropriate flavour of JSON with the same solr-xml-to-json.xsl
stylesheet.
I also changed the JSON-LD response to a request which has no search params but which Solr has returned no results for. Such a request now returns a JSON-LD graph describing it as a 404 error.
There is one minor caveat; a request which specifies a bad (i.e. unknown to Solr) parameter with no value will not itself produce an error (/object?title=dog&foo=
). This I think is a necessary corollary of the approach of making it Solr's responsibility for validating that parameters conform to the Solr metadata schema. We have been filtering out any URI parameters which have no value (on the basis that such empty parameters are not generally regarded as significant by web developers) before they are passed to Solr. If we didn't do that, then Solr would treat them as an explicit search for a blank value. But if they are filtered out, then Solr never gets a chance to complain that they violate its schema. I think that tradeoff is OK.
Include a JSON body in API responses describing API errors. See: http://jsonapi.org/format/#errors