diff --git a/jupyter_server/base/handlers.py b/jupyter_server/base/handlers.py index 770fff1866..6ceae2780b 100644 --- a/jupyter_server/base/handlers.py +++ b/jupyter_server/base/handlers.py @@ -36,6 +36,7 @@ from jupyter_server.utils import ( ensure_async, filefind, + is_sqlite_disk_full_error, url_escape, url_is_absolute, url_path_join, @@ -765,6 +766,9 @@ def write_error(self, status_code: int, **kwargs: Any) -> None: if isinstance(e, HTTPError): reply["message"] = e.log_message or message reply["reason"] = e.reason + elif is_sqlite_disk_full_error(e): + reply["message"] = "Disk is full" + reply["reason"] = str(e) else: reply["message"] = "Unhandled error" reply["reason"] = None diff --git a/jupyter_server/utils.py b/jupyter_server/utils.py index 0c987bff25..ff34e55faa 100644 --- a/jupyter_server/utils.py +++ b/jupyter_server/utils.py @@ -433,3 +433,12 @@ class JupyterServerAuthWarning(RuntimeWarning): Intended for filtering out expected warnings in tests, including downstream tests, rather than for users to silence this warning. """ + + +def is_sqlite_disk_full_error(e: Exception) -> bool: + try: + import sqlite3 + + return isinstance(e, sqlite3.OperationalError) and e.sqlite_errorcode == sqlite3.SQLITE_FULL # type: ignore[attr-defined] + except (AttributeError, ImportError) as e: + return "database or disk is full" in str(e)