mirror of
https://github.com/simonw/datasette.git
synced 2026-07-09 09:04:42 +02:00
Unify JSON error responses into one canonical shape
All JSON error responses now use a single format built by the new
datasette.utils.error_body() helper:
{"ok": false, "error": "...", "errors": ["..."], "status": 400}
- error is all messages joined with '; ', errors is the full list,
status always matches the HTTP status code
- The exception handler no longer emits the legacy title key in JSON
(it is still available to the HTML error template)
- The permission debug endpoints (/-/allowed, /-/rules, /-/check,
POST /-/permissions) no longer return bare {"error": ...} objects
- JSON renderer SQL errors keep their rows/truncated context keys but
now include the canonical keys as well
- _shape=object misuse (queries or tables without primary keys) now
returns HTTP 400 instead of 200 with an error body
- Method-not-allowed 405 responses use the canonical shape
Adds tests/test_error_shape.py covering all four previous shape
producers, updates affected tests, and documents the format in a new
'Error responses' section of docs/json_api.rst.
Implements section 1 of stable-api-recommendations.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
parent
8985ecf438
commit
0679e04bd3
15 changed files with 429 additions and 169 deletions
|
|
@ -323,20 +323,21 @@ def test_sql_time_limit(app_client_shorter_time_limit):
|
|||
"/fixtures/-/query.json?sql=select+sleep(0.5)",
|
||||
)
|
||||
assert 400 == response.status
|
||||
expected_message = (
|
||||
"<p>SQL query took too long. The time limit is controlled by the\n"
|
||||
'<a href="https://docs.datasette.io/en/stable/settings.html#sql-time-limit-ms">sql_time_limit_ms</a>\n'
|
||||
"configuration option.</p>\n"
|
||||
'<textarea style="width: 90%">select sleep(0.5)</textarea>\n'
|
||||
"<script>\n"
|
||||
'let ta = document.querySelector("textarea");\n'
|
||||
'ta.style.height = ta.scrollHeight + "px";\n'
|
||||
"</script>"
|
||||
)
|
||||
assert response.json == {
|
||||
"ok": False,
|
||||
"error": (
|
||||
"<p>SQL query took too long. The time limit is controlled by the\n"
|
||||
'<a href="https://docs.datasette.io/en/stable/settings.html#sql-time-limit-ms">sql_time_limit_ms</a>\n'
|
||||
"configuration option.</p>\n"
|
||||
'<textarea style="width: 90%">select sleep(0.5)</textarea>\n'
|
||||
"<script>\n"
|
||||
'let ta = document.querySelector("textarea");\n'
|
||||
'ta.style.height = ta.scrollHeight + "px";\n'
|
||||
"</script>"
|
||||
),
|
||||
"error": expected_message,
|
||||
"errors": [expected_message],
|
||||
"status": 400,
|
||||
"title": "SQL Interrupted",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -350,7 +351,7 @@ async def test_custom_sql_time_limit(ds_client):
|
|||
"/fixtures/-/query.json?sql=select+sleep(0.01)&_timelimit=5",
|
||||
)
|
||||
assert response.status_code == 400
|
||||
assert response.json()["title"] == "SQL Interrupted"
|
||||
assert response.json()["error"].startswith("<p>SQL query took too long.")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue