Skip to content

Commit

Permalink
error/truncated aruments for renderers, refs #2130
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Aug 7, 2023
1 parent 8ec6bc8 commit cd1dd01
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 8 deletions.
18 changes: 11 additions & 7 deletions datasette/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def convert_specific_columns_to_json(rows, columns, json_cols):
return new_rows


def json_renderer(args, data, view_name, truncated=None):
def json_renderer(args, data, error, truncated=None):
"""Render a response as JSON"""
status_code = 200

Expand All @@ -47,8 +47,12 @@ def json_renderer(args, data, view_name, truncated=None):
# Deal with the _shape option
shape = args.get("_shape", "objects")
# if there's an error, ignore the shape entirely
if data.get("error"):
data["ok"] = True
if error:
shape = "objects"
status_code = 400
data["error"] = error
data["ok"] = False

if truncated is not None:
data["truncated"] = truncated
Expand All @@ -67,13 +71,13 @@ def json_renderer(args, data, view_name, truncated=None):
if rows and columns:
data["rows"] = [dict(zip(columns, row)) for row in rows]
if shape == "object":
error = None
shape_error = None
if "primary_keys" not in data:
error = "_shape=object is only available on tables"
shape_error = "_shape=object is only available on tables"
else:
pks = data["primary_keys"]
if not pks:
error = (
shape_error = (
"_shape=object not available for tables with no primary keys"
)
else:
Expand All @@ -82,8 +86,8 @@ def json_renderer(args, data, view_name, truncated=None):
pk_string = path_from_row_pks(row, pks, not pks)
object_rows[pk_string] = row
data = object_rows
if error:
data = {"ok": False, "error": error}
if shape_error:
data = {"ok": False, "error": shape_error}
elif shape == "array":
data = data["rows"]

Expand Down
1 change: 1 addition & 0 deletions datasette/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ async def get(self, request):
request=request,
view_name=self.name,
truncated=False, # TODO: support this
error=data.get("error"),
# These will be deprecated in Datasette 1.0:
args=request.args,
data=data,
Expand Down
3 changes: 2 additions & 1 deletion datasette/views/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ async def query_view(
message_is_html=True,
)
except sqlite3.DatabaseError as ex:
query_error = ex
query_error = str(ex)
results = None
rows = []
columns = []
Expand Down Expand Up @@ -395,6 +395,7 @@ async def fetch_data_for_csv(request, _next=None):
request=request,
view_name="table",
truncated=results.truncated if results else False,
error=query_error,
# These will be deprecated in Datasette 1.0:
args=request.args,
data={"rows": rows, "columns": columns},
Expand Down
1 change: 1 addition & 0 deletions datasette/views/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ async def fetch_data(request, _next=None):
request=request,
view_name="table",
truncated=False,
error=None,
# These will be deprecated in Datasette 1.0:
args=request.args,
data=data,
Expand Down
6 changes: 6 additions & 0 deletions docs/plugin_hooks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,12 @@ When a request is received, the ``"render"`` callback function is called with ze
``request`` - :ref:`internals_request`
The current HTTP request.

``error`` - string or None
If an error occurred this string will contain the error message.

``truncated`` - bool or None
If the query response was truncated - for example a SQL query returning more than 1,000 results where pagination is not available - this will be ``True``.

``view_name`` - string
The name of the current view being called. ``index``, ``database``, ``table``, and ``row`` are the most important ones.

Expand Down

0 comments on commit cd1dd01

Please sign in to comment.