Add Response.error() for JSON errors in the standard format

Response.error(messages, status=400) builds a JSON error response in
Datasette's standard error format, alongside Response.json/html/text.
messages can be a single string or a list. All internal error response
construction now uses it - the private views.base._error() helper is
gone and the verbose Response.json(error_body(...), status=...) sites
are converted. error_body() remains for the cases that merge the error
keys into a larger payload (the JSON renderer, handle_exception and the
permission debug payload builders).

Since Response is public plugin API, plugins that build JSON endpoints
now have an obvious way to return errors in the canonical shape.
Documented in the internals documentation, including the guidance to
raise Forbidden/NotFound/BadRequest/DatasetteError instead when the
error should content-negotiate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
Claude 2026-07-06 23:48:49 +00:00
commit 8b159144a5
No known key found for this signature in database
12 changed files with 182 additions and 140 deletions

View file

@ -284,7 +284,7 @@ For example:
content_type="application/xml; charset=utf-8",
)
The quickest way to create responses is using the ``Response.text(...)``, ``Response.html(...)``, ``Response.json(...)`` or ``Response.redirect(...)`` helper methods:
The quickest way to create responses is using the ``Response.text(...)``, ``Response.html(...)``, ``Response.json(...)``, ``Response.error(...)`` or ``Response.redirect(...)`` helper methods:
.. code-block:: python
@ -295,6 +295,8 @@ The quickest way to create responses is using the ``Response.text(...)``, ``Resp
text_response = Response.text(
"This will become utf-8 encoded text"
)
# A JSON error in Datasette's standard error format:
error_response = Response.error("Cannot do that", 400)
# Redirects are served as 302, unless you pass status=301:
redirect_response = Response.redirect(
"https://latest.datasette.io/"
@ -304,6 +306,8 @@ Each of these responses will use the correct corresponding content-type - ``text
Each of the helper methods take optional ``status=`` and ``headers=`` arguments, documented above.
``Response.error(messages, status=400)`` returns a JSON error in the :ref:`standard Datasette error format <json_api_errors>`. ``messages`` can be a single string or a list of strings. Use this for JSON-only endpoints; if your error should content-negotiate between JSON and HTML, raise ``Forbidden``, ``NotFound``, ``BadRequest`` or ``DatasetteError`` instead and Datasette's error handling will build the appropriate response.
.. _internals_response_asgi_send:
Returning a response with .asgi_send(send)