mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-09-14 21:58:00 +00:00
Route SCHEMA_FIELD_MISSING into an error, not an HTTP 400
This commit is contained in:
@@ -82,7 +82,7 @@ class TestEmitErrorRouting:
|
||||
_map_emit_error(error)
|
||||
assert excinfo.value is error
|
||||
|
||||
def test_misconfigured_cause_is_logged_and_becomes_a_400(
|
||||
def test_misconfigured_cause_is_logged_and_reraised(
|
||||
self,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
@@ -92,15 +92,21 @@ class TestEmitErrorRouting:
|
||||
WHEN:
|
||||
- _map_emit_error processes it
|
||||
THEN:
|
||||
- It becomes a SearchQueryError, and exactly one ERROR log
|
||||
record is emitted naming the field and the diagnostic kind
|
||||
- Exactly one ERROR log record is emitted naming the field and
|
||||
the diagnostic kind, and the original QueryError propagates
|
||||
unchanged: a registry/schema disagreement is transient (the
|
||||
exact same query succeeds once the index is rebuilt), so it
|
||||
surfaces as a 500 an operator can see rather than a 400
|
||||
telling the client their query is permanently invalid
|
||||
"""
|
||||
kind = DiagnosticKind.SCHEMA_FIELD_MISSING
|
||||
with caplog.at_level(logging.ERROR, logger="paperless.search"):
|
||||
error = _map_emit_error(
|
||||
QueryError(_diagnostic(kind, field=FieldRef("asn"))),
|
||||
)
|
||||
assert isinstance(error, SearchQueryError)
|
||||
error = QueryError(_diagnostic(kind, field=FieldRef("asn")))
|
||||
with (
|
||||
caplog.at_level(logging.ERROR, logger="paperless.search"),
|
||||
pytest.raises(QueryError) as excinfo,
|
||||
):
|
||||
_map_emit_error(error)
|
||||
assert excinfo.value is error
|
||||
errors = [r for r in caplog.records if r.levelno == logging.ERROR]
|
||||
assert len(errors) == 1
|
||||
assert "asn" in errors[0].getMessage()
|
||||
@@ -144,7 +150,6 @@ class TestEmitErrorRouting:
|
||||
DiagnosticKind.TEXT_RANGE,
|
||||
DiagnosticKind.PATTERN_TOO_COMPLEX,
|
||||
DiagnosticKind.EXISTS_REQUIRES_FAST,
|
||||
DiagnosticKind.SCHEMA_FIELD_MISSING,
|
||||
],
|
||||
)
|
||||
def test_user_facing_message_never_echoes_library_prose(
|
||||
@@ -154,7 +159,10 @@ class TestEmitErrorRouting:
|
||||
"""
|
||||
GIVEN:
|
||||
- A QueryError carrying whoosh-compat's own developer-facing
|
||||
message text
|
||||
message text (SCHEMA_FIELD_MISSING excluded: it is now
|
||||
re-raised rather than converted, so it never produces a
|
||||
user-facing message at all, see
|
||||
test_misconfigured_cause_is_logged_and_reraised)
|
||||
WHEN:
|
||||
- _map_emit_error processes it
|
||||
THEN:
|
||||
@@ -170,7 +178,6 @@ class TestEmitErrorRouting:
|
||||
DiagnosticKind.TEXT_RANGE,
|
||||
DiagnosticKind.PATTERN_TOO_COMPLEX,
|
||||
DiagnosticKind.EXISTS_REQUIRES_FAST,
|
||||
DiagnosticKind.SCHEMA_FIELD_MISSING,
|
||||
],
|
||||
)
|
||||
def test_user_facing_message_names_the_field(
|
||||
|
||||
@@ -9,7 +9,10 @@ action can clear the condition. Any authenticated user could otherwise emit
|
||||
ERROR lines in a loop by repeating ``notes:*``.
|
||||
|
||||
SCHEMA_FIELD_MISSING, the other MISCONFIGURED kind, does compare the registry
|
||||
against the live schema, so it stays an ERROR.
|
||||
against the live schema, so it stays an ERROR log. But it is not a 400
|
||||
either: the exact same query would succeed once the index is rebuilt, so it
|
||||
is a transient server-side condition, not a permanently bad request, and is
|
||||
re-raised the same way an INTERNAL cause is.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -81,7 +84,7 @@ class TestJsonExistsIsUserError:
|
||||
|
||||
|
||||
class TestGenuineMisconfigurationStillLogs:
|
||||
def test_schema_field_missing_is_an_error_log(
|
||||
def test_schema_field_missing_is_an_error_log_and_reraised(
|
||||
self,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
@@ -92,9 +95,13 @@ class TestGenuineMisconfigurationStillLogs:
|
||||
WHEN:
|
||||
- _map_emit_error processes it
|
||||
THEN:
|
||||
- It becomes a SearchQueryError and logs exactly one ERROR
|
||||
record naming the diagnostic kind, since this is a real
|
||||
mismatch an operator can fix and keeps the alert
|
||||
- It logs exactly one ERROR record naming the diagnostic kind
|
||||
(a real mismatch an operator can fix, so it keeps the
|
||||
alert), and the original QueryError propagates unchanged
|
||||
rather than becoming a SearchQueryError: the exact same
|
||||
query would succeed once the index is rebuilt, so this is a
|
||||
transient server-side condition, not a permanently bad
|
||||
request, and surfaces as a 500 rather than a 400
|
||||
"""
|
||||
kind = DiagnosticKind.SCHEMA_FIELD_MISSING
|
||||
error = QueryError(
|
||||
@@ -106,9 +113,12 @@ class TestGenuineMisconfigurationStillLogs:
|
||||
field_kind=FieldKind.U64,
|
||||
),
|
||||
)
|
||||
with caplog.at_level(logging.ERROR, logger="paperless.search"):
|
||||
mapped = _map_emit_error(error)
|
||||
assert isinstance(mapped, SearchQueryError)
|
||||
with (
|
||||
caplog.at_level(logging.ERROR, logger="paperless.search"),
|
||||
pytest.raises(QueryError) as excinfo,
|
||||
):
|
||||
_map_emit_error(error)
|
||||
assert excinfo.value is error
|
||||
records = [r for r in caplog.records if r.levelno == logging.ERROR]
|
||||
assert len(records) == 1
|
||||
assert kind.name in records[0].getMessage()
|
||||
|
||||
Reference in New Issue
Block a user