XMLDocumentManager.exists() may throw exceptions on server side
Closed this issue · 2 comments
When checking for documents to exist in our MarkLogic server database we tend to use
XMLDocumentManager#exists(String... uris). This method call produces a REST request ending up in /MarkLogic/rest-api/models/document-model-query.xqy.
Our problem is, that if the document (to check for) is missing then this method then produces a ~5000 character long error stacktrace, polluting our server side logs.
I did create an issue for MarkLogic Server (Case 01571131) because using exceptions as control flow is - simply put - bad software design. And why should an exception be thrown anyway? Either a document exists or it doesn't. Nothing surprising or exceptional about it.
I'm raising this issue here because maybe there are other REST-API-methods to chose from? Maybe there is something less intrusive? - Don't know.
Meanwhile we are tempted to no longer use XMLDocumentManager#exists(String... uris) but instead perform an eval-script which checks for a document without so much noice.
Thoughts?
PS: Using marklogic-java-client in version 7.0.0 and ML server in version 11.3.1
Hey @ralfhergert - I'm not able to get that same stacktrace. The exists(String) method is sending a HEAD request to v1/documents. I can do the same thing with curl:
curl --head --anyauth -u admin:admin "http://localhost:8004/v1/documents?uri=/missing.xml"
And I see the following in my 8004 access logs, with nothing written to the error log:
192.168.65.1 - - [03/Dec/2024:17:12:56 +0000] "HEAD /v1/documents?uri=/missing.xml HTTP/1.1" 401 0 - "curl/8.7.1"
192.168.65.1 - admin [03/Dec/2024:17:12:56 +0000] "HEAD /v1/documents?uri=/missing.xml HTTP/1.1" 404 0 - "curl/8.7.1"
For other options, particularly if you want to check the existence of multiple URIs - I would consider an Optic query for that - e.g. something like this (which you can construct using the Java PlanBuilder too):
op.fromSearchDocs(cts.documentQuery(/*put each URI in here*/))
.select(["uri"])
That would return each URI that exists.
Thank you for your quick response, @rjrudin
Just testing with a curl statement is a good idea, I tried that, and I could find the accoring error message in my logs:
2024-12-04 11:22:56.826 Notice: RESTAPI-NODOCUMENT: (err:FOER0000) Resource or document does not exist: category: content message: /missing.xml
2024-12-04 11:22:56.826 Notice:+in /MarkLogic/rest-api/models/document-model-query-head.xqy, at 78:13,
2024-12-04 11:22:56.826 Notice:+in docmodqryhead:head(map:map(<map:map xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" .../>), map:map(<map:map xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" .../>)) [1.0-ml]
2024-12-04 11:22:56.826 Notice:+ $headers = map:map(<map:map xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" .../>)
2024-12-04 11:22:56.826 Notice:+ $params = map:map(<map:map xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" .../>)
2024-12-04 11:22:56.826 Notice:+ $uri = "/missing.xml"
2024-12-04 11:22:56.826 Notice:+ $uri-format = "xml"
2024-12-04 11:22:56.826 Notice:+ $accept-type = ()
2024-12-04 11:22:56.826 Notice:+ $doc = ()
2024-12-04 11:22:56.826 Notice:+ $response-format = "xml"
2024-12-04 11:22:56.826 Notice:+ $uri-type = "application/xml"
2024-12-04 11:22:56.826 Notice:+ $response-type = "application/xml"
2024-12-04 11:22:56.826 Notice:+ $skip-etag = fn:false()
2024-12-04 11:22:56.826 Notice:+ $version = ()
2024-12-04 11:22:56.826 Notice:+ $is-available = fn:false()
2024-12-04 11:22:56.826 Notice:+in /MarkLogic/rest-api/endpoints/document-item-query-head.xqy, at 48:9 [1.0-ml]
I think in order to see this error message, "System Level Logs" must be configured to show at least "NOTICE". (Not sure whether this is the case by default.)
But thanks for your hints on alternative methods to test for document existence. I'll give it a shot.
Closing this issue.