docs: correct three stale pointers in the search comments and admin docs

_map_emit_error's docstring pointed at the QueryParserError arm of views.py's
generic handler, which was deleted; QueryParserError no longer appears in
production code at all. _REGEX_TIMEOUT justified itself as ReDoS protection,
but the two pre-parse rewrites it was written for are gone and its one
remaining use is a character class that cannot backtrack. The timeout stays,
its rationale is corrected. administration.md listed two triggers for
--if-needed; the schema fingerprint is now a third.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
stumpylog
2026-08-20 12:14:31 -07:00
co-authored by Claude Opus 5
parent 0d609074dd
commit d17232043b
2 changed files with 11 additions and 8 deletions
+2 -1
View File
@@ -521,7 +521,8 @@ Pass `--recreate` to wipe the existing index before rebuilding. Use this when th
index is corrupted or you want a fully clean rebuild.
Pass `--if-needed` to skip the rebuild if the index is already up to date (schema
version and search language match). Safe to run on every startup or upgrade.
version, schema fingerprint and search language all match). Safe to run on every
startup or upgrade.
Specify `optimize` to optimize the index. This command is regularly invoked by the
task scheduler.
+9 -7
View File
@@ -26,8 +26,10 @@ if TYPE_CHECKING:
logger = logging.getLogger("paperless.search")
# Maximum seconds any single regex substitution may run.
# Prevents ReDoS on adversarial user-supplied query strings.
# Maximum seconds any single regex substitution over user-supplied query text
# may run. The one remaining use is a character class, which cannot backtrack,
# so the bound is an upper limit on that substitution's cost, not the ReDoS
# guard it was originally written as.
_REGEX_TIMEOUT: Final[float] = 1.0
# Matches CJK/Hangul characters so queries can be routed to bigram fields.
@@ -62,11 +64,11 @@ def _map_emit_error(e: QueryError) -> SearchQueryError:
INVALID_INPUT/UNSUPPORTED are user-input errors, exactly like a parse
diagnostic, and map to a 400. INTERNAL means a defect in whoosh-compat
or in our own AST handling, never the user's query, so the QueryError is
re-raised to surface the same way views.py already lets QueryParserError
surface. MISCONFIGURED is deliberately both: the registry and the index
schema disagree, which only an operator can fix, so it is logged as an
error, but a request is still waiting and the query cannot run either
way, so it also returns a 400.
re-raised rather than converted, reaching the generic 500 handler instead
of blaming the query. MISCONFIGURED is deliberately both: the registry and
the index schema disagree, which only an operator can fix, so it is logged
as an error, but a request is still waiting and the query cannot run
either way, so it also returns a 400.
EXISTS_REQUIRES_FAST is the one MISCONFIGURED kind that is not a
disagreement. whoosh-compat derives it from the registry's own FieldSpec