Skip to content

[bugfix] Raise err:FODC0002 from fn:doc and fn:collection on failed retrieval - #6812

Open
line-o wants to merge 3 commits into
eXist-db:developfrom
line-o:fix/3898-fn-doc-errors
Open

line-o wants to merge 3 commits into
eXist-db:developfrom
line-o:fix/3898-fn-doc-errors

Conversation

@line-o

@line-o line-o commented Oct 7, 2026

Copy link
Copy Markdown
Member

Description:

fn:doc and fn:collection now raise err:FODC0002 when a resource or collection cannot be retrieved, instead of returning the empty sequence. This is what the specification requires.

Warning

Breaking change. Code that tests for existence with doc(…) or collection(…) (for example if (doc($uri)) … or exists(collection($c)/*)) now raises an error when the resource is missing. Migrate such checks to fn:doc-available() / xmldb:collection-available(), or catch err:FODC0002. Installations that need time to migrate can set raise-error-on-failed-retrieval="no" on <xquery> in conf.xml.

What changed

Default of raise-error-on-failed-retrieval is now yes. The existing switch is enabled by default in conf.xml, conf.xsd (bumped to 2.8.0) and XQueryContext, which until now read the property with a hard-coded false fallback. The switch covers fn:doc, fn:collection and xmldb:xcollection. The documentation no longer mentions xmldb:document(), which no longer exists.

fn:doc error mapping (FunDoc). Before this change, every exception was rewrapped as FODC0005, including the FODC0002 raised when the switch was on. Now:

Condition Before After
$uri is not a valid URI FODC0005 FODC0005
no document at the URI () FODC0002
permission denied FODC0005 FODC0002
binary resource, unparseable XML, HTTP status other than 200 FODC0005 FODC0002

fn:doc-available is unchanged: it returns false in all of the "after: FODC0002" cases.

fn:collection (ExtCollection). A relative URI with no base URI now raises FODC0002, as the spec requires, instead of FODC0003. A missing collection raises FODC0002 through the switch.

FODC0003 (determinism) is documented rather than implemented. Both function descriptions now state that results are not stable, because resources can be changed by other transactions while a query runs.

The F&O 3.1 error conditions for fn:collection, compared with develop, are written up in #3898 (comment).

fn:transform fix (separate commit). named-template-document in doc-as-parameter.xqm built its path without a /, so it had always passed the empty sequence (found by @joewiz). With the path fixed, a ClassCastException appeared: Convert.ToSaxon.of(Item) cast a stored document (NodeProxy) to org.w3c.dom.Node. The fix unwraps NodeProxy in the same way of(Sequence) already did.

Tests that relied on the empty sequence:

  • DOMIndexerTest: the query ran concurrently with, and independently of, the test that stores its document, so it queried a missing collection and asserted nothing. The store now runs in @BeforeAll, and the query asserts its result.
  • DeadlockIT: query tasks race against tasks that remove documents and collections, so a missing resource is an expected outcome. The queries now catch err:FODC0002.
  • expathrepo/deployment.xql: existence checks now use doc-available / xmldb:collection-available.
  • lucene/ft-query-forms.xqm: index-keys-nonexistent-collection now expects err:FODC0002.
  • range/range.xql: remove-document re-read the removed document with doc(), which never exercised the index. It now queries the collection index and filters for the removed document.

Reference:

Closes #3898

Per @joewiz's analysis in the issue, this should also make qt3tests fn-doc-3 and K2-SeqDocFunc-3, -4, -6, -10 and -11 pass. I have not run them through the XQTS runner locally.

Type of tests:

  • XQSuite (fn.xql): fn:doc on a missing document, a binary resource, an invalid URI, (), and a document guest cannot read (with fn:doc-available returning false for it); fn:collection on a missing and an existing collection.
  • Run locally, all green: the full exist-core test suite (7409 tests), DeadlockIT, all extensions modules, mvn -N validate, and schema governance.
  • Independent of [test] Isolate XQSuite test files, run CoreTests and XQuery3Tests in parallel #6796 (XQSuite isolation). Both PRs touch ft-query-forms.xqm and range.xql, but in different tests. Cherry-picked onto [test] Isolate XQSuite test files, run CoreTests and XQuery3Tests in parallel #6796 (366ccfa), they apply without conflicts, and these suites are green, the XQSuites running files in parallel: CoreTests, XQuery3Tests, OptimizerTests, RangeTests, LuceneTests, ExpathRepoTests, FileTests and XmlDiffTests.

🤖 Generated with Claude Code

final DocumentSet docs = result.getDocumentSet();
if (docs != null && DocumentSet.EMPTY_DOCUMENT_SET != docs) {
// only cache node sets (which have a non-empty document set)
registerUpdateListener();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to check what this does

@dizzzz
dizzzz requested review from a team, reinhapa and wolfgangmm October 7, 2026 16:02
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

📊 XQTS result comparison

Comparison of this run against develop.

Metric develop this run Change
🟢 Passed 28,868 (90.74%) 28,870 (90.74%) +2 (+0.01 pp)
🟢 Failures 1,546 1,544 -2
➖ Errors 134 134 0
➖ Skipped 1,267 1,267 0
🧪 Total tests 31,815 31,815 0

Relative to develop: 2 newly passing, 0 newly failing, 0 new errors, 0 newly skipped — counting only tests recorded in both runs whose outcome changed.

🟢 Newly passing tests (2)
  • fn-doc-35 (was failing)
  • K2-SeqDocFunc-13 (was failing)

Runtime: 354.6s (-156.06s vs develop).

line-o and others added 3 commits October 9, 2026 13:28
Convert.ToSaxon.of(Item) cast every node item to org.w3c.dom.Node, which
fails with a ClassCastException for a NodeProxy, e.g. a stored document
passed as "global-context-item". of(Sequence) already unwrapped a
NodeProxy; do the same for single items.

The named-template-document test in doc-as-parameter.xqm should have
caught this, but built the document path without a "/" separator, so
fn:doc silently returned the empty sequence and no node was converted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…etrieval

The XQuery and XPath Functions 3.1 specification requires fn:doc and
fn:collection to raise err:FODC0002 when the resource cannot be
retrieved. eXist-db returned the empty sequence unless
raise-error-on-failed-retrieval was enabled, and even then fn:doc
rewrapped the error as err:FODC0005.

- default raise-error-on-failed-retrieval to "yes" (conf.xml, conf.xsd
  and XQueryContext); "no" remains as an opt-out while applications
  migrate existence checks to fn:doc-available and
  xmldb:collection-available. This also applies to xmldb:xcollection.
- fn:doc: raise err:FODC0005 only for an invalid URI; raise err:FODC0002
  for a missing, unreadable, binary or unparseable resource
- fn:collection: raise err:FODC0002 instead of err:FODC0003 for a
  relative URI without a base URI
- document the error behaviour and that results are not stable
  (err:FODC0003 is never raised)
- bump conf.xsd to 2.8.0 for the changed default

Tests that relied on the empty sequence for missing resources now use
fn:doc-available / xmldb:collection-available, expect err:FODC0002, or
no longer race against their own setup (DOMIndexerTest, DeadlockIT).

Closes eXist-db#3898

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nusable

An invalid static base URI (e.g. declare base-uri "c:\windows") made
fn:doc leak err:FORG0001 from the XmldbURI conversion. Previously the
catch-all in FunDoc masked this as err:FODC0005; report that code
explicitly so the relative URI resolution failure keeps a fn:doc error.

Fixes W3C XQTS K2-BaseURIProlog-3.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@line-o
line-o force-pushed the fix/3898-fn-doc-errors branch from e74aca3 to c4d41bc Compare October 9, 2026 11:44

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] fn:doc should raise an error if the resource cannot be retrieved

2 participants