mirror of
https://github.com/simonw/datasette.git
synced 2026-10-18 15:26:57 +02:00
Merge bf89514c74 into cf113a5985
This commit is contained in:
commit
1cc6f3e0f6
3 changed files with 30 additions and 42 deletions
|
|
@ -1,6 +1,9 @@
|
|||
import csv
|
||||
import hashlib
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
import markupsafe
|
||||
|
||||
from datasette.utils import (
|
||||
EscapeHtmlWriter,
|
||||
|
|
@ -39,6 +42,29 @@ class DatasetteError(Exception):
|
|||
self.plain_message = plain_message
|
||||
|
||||
|
||||
def query_interrupted_error(ex):
|
||||
"""The SQL time limit error page, shared by every view that runs user SQL."""
|
||||
return DatasetteError(
|
||||
textwrap.dedent(f"""
|
||||
<p>SQL query took too long. The time limit is controlled by the
|
||||
<a href="https://docs.datasette.io/en/stable/settings.html#sql-time-limit-ms">sql_time_limit_ms</a>
|
||||
configuration option.</p>
|
||||
<textarea style="width: 90%">{markupsafe.escape(ex.sql)}</textarea>
|
||||
<script>
|
||||
let ta = document.querySelector("textarea");
|
||||
ta.style.height = ta.scrollHeight + "px";
|
||||
</script>
|
||||
""").strip(),
|
||||
title="SQL Interrupted",
|
||||
status=400,
|
||||
message_is_html=True,
|
||||
plain_message=(
|
||||
"SQL query took too long. The time limit is"
|
||||
" controlled by the sql_time_limit_ms setting."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class View:
|
||||
async def head(self, request, datasette):
|
||||
if not hasattr(self, "get"):
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import hashlib
|
|||
import itertools
|
||||
import json
|
||||
import os
|
||||
import textwrap
|
||||
from dataclasses import asdict, dataclass, field
|
||||
from urllib.parse import parse_qsl, urlencode
|
||||
|
||||
|
|
@ -39,7 +38,7 @@ from datasette.utils.asgi import AsgiFileDownload, Forbidden, NotFound, Response
|
|||
from datasette.write_sql import QueryWriteRejected
|
||||
|
||||
from . import Context
|
||||
from .base import DatasetteError, View, stream_csv
|
||||
from .base import DatasetteError, View, query_interrupted_error, stream_csv
|
||||
from .query_helpers import (
|
||||
_block_framing,
|
||||
_ensure_stored_query_execution_permissions,
|
||||
|
|
@ -819,25 +818,7 @@ class QueryView(View):
|
|||
columns = results.columns
|
||||
rows = results.rows
|
||||
except QueryInterrupted as ex:
|
||||
raise DatasetteError(
|
||||
textwrap.dedent(f"""
|
||||
<p>SQL query took too long. The time limit is controlled by the
|
||||
<a href="https://docs.datasette.io/en/stable/settings.html#sql-time-limit-ms">sql_time_limit_ms</a>
|
||||
configuration option.</p>
|
||||
<textarea style="width: 90%">{markupsafe.escape(ex.sql)}</textarea>
|
||||
<script>
|
||||
let ta = document.querySelector("textarea");
|
||||
ta.style.height = ta.scrollHeight + "px";
|
||||
</script>
|
||||
""").strip(),
|
||||
title="SQL Interrupted",
|
||||
status=400,
|
||||
message_is_html=True,
|
||||
plain_message=(
|
||||
"SQL query took too long. The time limit is"
|
||||
" controlled by the sql_time_limit_ms setting."
|
||||
),
|
||||
)
|
||||
raise query_interrupted_error(ex)
|
||||
except sqlite3.DatabaseError as ex:
|
||||
query_error = str(ex)
|
||||
results = None
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import asyncio
|
||||
import json
|
||||
import textwrap
|
||||
import time
|
||||
import urllib.parse
|
||||
from dataclasses import dataclass, field
|
||||
|
|
@ -35,7 +34,7 @@ from datasette.utils.asgi import Forbidden, NotFound, PayloadTooLarge, Response
|
|||
from datasette.utils.sqlite import check_structured_write_table
|
||||
|
||||
from . import Context, from_extra
|
||||
from .base import BaseView, DatasetteError, stream_csv
|
||||
from .base import BaseView, DatasetteError, query_interrupted_error, stream_csv
|
||||
from .table import (
|
||||
_table_page_data,
|
||||
display_columns_and_rows,
|
||||
|
|
@ -195,25 +194,7 @@ class RowView(BaseView):
|
|||
else:
|
||||
data, extra_template_data, templates = response_or_template_contexts
|
||||
except QueryInterrupted as ex:
|
||||
raise DatasetteError(
|
||||
textwrap.dedent(f"""
|
||||
<p>SQL query took too long. The time limit is controlled by the
|
||||
<a href="https://docs.datasette.io/en/stable/settings.html#sql-time-limit-ms">sql_time_limit_ms</a>
|
||||
configuration option.</p>
|
||||
<textarea style="width: 90%">{markupsafe.escape(ex.sql)}</textarea>
|
||||
<script>
|
||||
let ta = document.querySelector("textarea");
|
||||
ta.style.height = ta.scrollHeight + "px";
|
||||
</script>
|
||||
""").strip(),
|
||||
title="SQL Interrupted",
|
||||
status=400,
|
||||
message_is_html=True,
|
||||
plain_message=(
|
||||
"SQL query took too long. The time limit is"
|
||||
" controlled by the sql_time_limit_ms setting."
|
||||
),
|
||||
)
|
||||
raise query_interrupted_error(ex)
|
||||
except (sqlite3.OperationalError, InvalidSql) as e:
|
||||
raise DatasetteError(str(e), title="Invalid SQL", status=400)
|
||||
except DatasetteError:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue