Open hanshuebner opened 7 years ago
If in /eval, on line 19 expr
part of xquery stacktrace pointed to the right document location, it is possible to write compilation-minor-mode compatible regex. It's possible to navigate with next-error and previous-error keys.
Is it what are you looking for?
Exactly, the error location in the XQuery evaluator stack trace is accurate and currently, I'm locating the error manually by looking at the on line 63 expr
lines. Also, it would be good if the XQuery stack traces would be alone, not mixed with the Clojure stack traces. If that is possible at all.
In the branch error-buffer
following behavior is implemented:
xquery version "1.0-ml";
module namespace hello = "helloworld";
declare function helloworld()
{
<foo>
};
XQueryException com.marklogic.xcc.exceptions.XQueryException: XDMP-BADCHAR: (err:XPST0003) Unexpected character found '}' (0x007d)
[Session: user=proofit404, cb=TutorialDB [ContentSource: user=proofit404, cb=TutorialDB [provider: address=localhost/127.0.0.1:8889, pool=1/64]]]
[Client: XCC/8.0-5, Server: XDBC/8.0-5.8]
on line 7
expr: com.marklogic.xcc.impl.handlers.ServerExceptionHandler.handleResponse (ServerExceptionHandler.java:34)
on line 7
phrase is highlighted Now things becomes more interesting when we speak about errors inside documents uploaded to the MarkLogic server. For example syntax error can be placed inside module on the other server. In my installation I store xquery modules in the /data/
directory on the remote server. Lets upload xquery module from previous example to the /data/e/test.xqy
to the marklogic host.
Now we open another xquery file localy
xquery version "1.0-ml";
import module namespace hw="helloworld" at "/e/test.xqy";
hw:helloworld()
XQueryException com.marklogic.xcc.exceptions.XQueryException: XDMP-BADCHAR: (err:XPST0003) Unexpected character found '}' (0x007d)
[Session: user=proofit404, cb=TutorialDB [ContentSource: user=proofit404, cb=TutorialDB [provider: address=localhost/127.0.0.1:8889, pool=1/64]]]
[Client: XCC/8.0-5, Server: XDBC/8.0-5.8]
in /e/test.xqy, on line 7
expr: com.marklogic.xcc.impl.handlers.ServerExceptionHandler.handleResponse (ServerExceptionHandler.java:34)
in /e/test.xqy, on line 7
phrase is highlightedPlease give it a try and let me know if any this is missing in this feature.
Hi, this starts to look nice! For now, there seem to be some problems.
But all together, this look promising. Good work! Maybe make the messages more readable by moving less interesting information down. Have a look at:
XQueryException com.marklogic.xcc.exceptions.XQueryException: XDMP-NOTANODE: (err:XPTY0019) 23 | 23 -- 23 is not a node
[Session: user=admin, cb={default} [ContentSource: user=admin, cb={none} [provider: address=localhost/127.0.0.1:8021, pool=1/64]]]
[Client: XCC/8.0-5, Server: XDBC/8.0-5.5]
on line 4
expr: 23 | 23 com.marklogic.xcc.impl.handlers.ServerExceptionHandler.handleResponse (ServerExceptionHandler.java:34)
The interesting part only starts after "XQueryException com.marklogic.xcc.exceptions.XQueryException: ", and the [Session...][Client...] lines cold be moved below the error message itself, right?
Bye, Max
Hi!
First of all I want to describe how it was implemented.
We have cider-any-eval-handler
which will take error reported by clojure uruk library. Error here is simply a string with traceback.
We show error buffer in any case without additional preprocessing.
Then if there is lines like "on line <num>"
or "in <doc>, on line <num>"
we will treat them as links to documents and support next or previous errors navigation.
Pretty simple, right?
Now let me explain each item in your list:
expr: ...
, that mean uruk library report it this way and there is nothing we can do about it. Error navigation based of line
marker not expr
anyway.2.1. Please, submit reproducible document if possible. You can skip it minimization.
xdmp:modules-database()
documentation careful, hope it is possible to use it in remote modules navigation.3.1. I don't think we need to move xdbc logic into cider-any-uruk. At least until we finish this branch.
Finally on error content modification. I think if we would modify it, we must do it in the clojure layer, when exception object is accessible. Not in Emacs Lisp when it only a string with new lines. I'll try to figure out if it possible based on current uruk code base.
Regards, Artem.
Hello guys, I'm stuck :(
I'm trying to implement content access for MarkLogic modules. While navigate in the error buffer I want to see the actual position in the module, which triggers error. For example we have this file:
xquery version "1.0-ml";
import module namespace sec="http://marklogic.com/xdmp/security" at "/MarkLogic/security.xqy";
sec:user-get-roles("Jim")
Now I type C-c C-c
. Following error buffer shows up:
XQueryException com.marklogic.xcc.exceptions.XQueryException: SEC-USERDNE: (err:FOER0000) User does not exist: sec:user-name = Jim
[Session: user=proofit404, cb=TutorialDB [ContentSource: user=proofit404, cb=TutorialDB [provider: address=localhost/127.0.0.1:8889, pool=1/64]]]
[Client: XCC/8.0-5, Server: XDBC/8.0-5.8]
in /MarkLogic/security.xqy, on line 3612
expr: ,
in get-element("http://marklogic.com/xdmp/security", "sec:user", "sec:user-name", "Jim", "SEC-USERDNE")
in /MarkLogic/security.xqy, on line 1265
expr: ,
in sec:user-get-roles("Jim")
on line 4
expr: com.marklogic.xcc.impl.handlers.ServerExceptionHandler.handleResponse (ServerExceptionHandler.java:34)
We see three frames of traceback for this error. The first one stays in the /MarkLogic/security.xqy
module. When I call next-error
command cursor will stays at front of the first in ...
expression and tries to open security module. This module stored in the modules database and I can obtain it with this xquery:
xdmp:document-get("/opt/MarkLogic/Modules/MarkLogic/security.xqy")
But how do I know this full path to the module? I try to google this solution for two days with out any success...
Then when I call next-error
one more time I expect cursor moves its position in the security buffer from 3612 to the 1265 line.
After next call to next-error
command we will stay inside our file in the line 4.
All this thing is working except I can't figure out how to obtain module content from module uri.
Also there are two possible scenarios according to "modules database" setting. It is related to modules which were uploaded ourselves. If we set "modules database" setting to the "(file system)", our modules will be loaded from file system root. To resolve those modules we need something like
if (xdmp:modules-database() = 0)
then
xdmp:document-get(fn:concat(xdmp:modules-root(), "/MarkLogic/security.xqy"))
else
...
But in general "modules database" setting will be set to something like "Modules" so our modules will be uploaded to this database too. I've tried to do something like this:
declare variable $module :=
<module>
<uri>/MarkLogic/security.xqy</uri>
</module>;
let $mdb := xdmp:modules-database()
xdmp:eval(fn:concat('xdmp:document-get("', $module/uri, '")'),
(),
<options xmlns="xdmp:eval">
<database>{$mdb}</database>
</options>)
But it doesn't do what I expect.
Any suggestions?
Regards, Artem.
Hi Artem,
Short answer: the Modules of the Marklogic installation itself are special. Try with a user Module that you've added yourself; it should work for that case.
Please have another look at how MarkLogic resolves paths on module loading: https://docs.marklogic.com/guide/app-dev/import_modules#id_29407
MARKLOGIC_INSTALL_DIR/Modules
(see /etc/sysconfig/MarkLogic
in Linux). And this Marklogic Modules directory is always asked first, and it isa filesystem location.The problem now are:
/MarkLogic/security.xqy
is part of MarkLogic and thus in the Modules directory of the MarkLogic installation, not in the modules filesystem location or modules database of the AppServer.
\ The location is a filesystem location relative to MARKLOGIC_INSTALL_DIR/Modules
on the MarkLogic server. This has nothing to do with the xdmp:modules-root().xdmp:filesystem-file(fn:concat("/opt/MarkLogic/Modules", "/MarkLogic/security.xqy"));
, and to have the proper permissions for that! I don't know how to retrieve the path of Marklogic's Modules directory from within XQuery or how to evaluate the environment variable MARKLOGIC_INSTALL_DIR
.xdmp:filesystem-file
, but now obeying xdmp:modules-root().My perspective on priorities:
Cheers, Max
PS: fn:concat(xdmp:modules-root(), "/MarkLogic/security.xqy")
might lead to a double slash.
As we say in Russia:
Either I'm a fool, or my skis not slide.
I've spent yet another two days trying to import a module from the modules database :(
I've tried every possible combination of xdmp:document-insert, xdmp:document-load, xdmp:permission. I just can't create importable module for my test purposes.
It will be very nice if you can write short instruction for dummies how to create importable module, how to upload it in to modules database, how to import it.
I introduced configurable variable for MarkLogic installation path. By default its value is "/opt/MarkLogic/". I need to note that Windows support will require slightly more efforts to implement. Now when we navigates through error list for each module uri we tries:
1) Find this module in /path/to/MarkLogic/Modules/uri/part/of/path.xqy This works reasonable well, if you setup this variable correctly.
2) If App Server uses (file system)
as its modules storage, we search given module on file system. This technique was discussed earlier.
3) If App Server uses Modules database, we will get this module content using fn:doc
.
I need to test last condition, by I failed to build necessary environment for it.
Regards, Artem.
Hi Artem,
Thanks that sounds quite. I'll make you a test example later. No worries, sometimes things behave strangely. Also I will give you feedback about the possible renaming etc.
Cheers Max
Hi,
here is a complete example.
A module: foo-module.xqy.txt
XQuery code to upload to MarkLogic when talking directly to the Modules database: foo-module-upload.xqy.txt
XQuery code to upload to MarkLogic when talking directly to another database database: foo-module-upload-from-content-base.xqy.txt
XQuery code to show the module when talking directly to the Modules database: foo-module-show.xqy.txt
XQuery code to show the module when talking to antother database: foo-module-show-from-content-base.xqy.txt
In general: Better not use xdmp:document-get()``, as we never want to fetch files from the web (i.e., over http). Either use
docto fetch from a xml database or use
xdmp:filesystem-file``` to retrieve files form the filesystem of the server.
Hope that helps, Max
I've followed your recommendations and it looks like it finally works. Thanks!!
Please check that it works in your environment too.
I still can't reproduce the case with empty error buffer. Maybe you will find those circumstances later.
NOTE: you should use error-buffer
branch in the Oook
repository since we've moved the code and not the issues.
Thank you! That sounds great. Currently, I'm very busy with a project and cannot change the tooling right now. But I noticed your code changes and I'm eager to use it. Thanks for already making the oook-selector repository and updating the code!
Oh, could you post screenshot of the error-buffer output? Did you rearrange the output a bit as suggested at the end of my comment in https://github.com/xquery-mode/cider-any/issues/13#issuecomment-254154280?
By the way, for said project I use all these facilities. Nice to use, also when talking to several MarkLogic instances at the same time. And also some queries are not only more convenient to do from Emacs than MarkLogic's Query Console but also some huge queries I get in below a second of response time while the Query Console takes 4-7 seconds. Isn't that nice? (I'm guessing that the Javascript does some post-processing for nice presentation that takes longer.)
Cheers, Max
Oh, could you post screenshot of the error-buffer output?
Did you rearrange the output a bit as suggested at the end of my comment in #13 (comment)?
Not yet, but I found the way which can probably work out. If this research will be successful we will have new output format soon.
By the way I'm glad you're like it!
Good morning!
I rearrange the output as suggested at the end of your comment.
Basically I reimplement exception representation from scratch in the clojure handler. It supersedes this and that methods.
Please test if it works for you and if it fits necessary information layout.
P.S. my clojure skills are weak so catch code looks not so good.
Very nice! I just have started to use it, so didn't have an in-depth look. So far very nice! Is there a key to show also the full Java stack trace? Just in case... Cheers, Max
Yes, it's possible. I will add it at the end of buffer.
Java stack trace now looks like this
There is a line at the end of the error buffer. It magically appended to original message somewhere outside of
oook
exception handler. I suspect this happens because we throw new exception within try/catch
block. It mostly a cosmetic trouble so I don't research it too much.
Right now, all exceptions are just printed using the standard cider exception handler:
It would be nice if the XQuery stacktrace was displayed instead. and if there was an easy way to navigate to the XQuery error location from there.