I’m glad you all find this reflection library useful. Since I don’t know what 
you want to use it for….

<obligatory-disclaimer>
Use this code carefully. In Roxy we use it to report an error. It’s not part of 
the critical execution path where performance would matter.
I wouldn’t go calling this thing all over your code. It’s a useful hack, but 
definitely not meant to be used willy nilly.

And if memory serves me correctly we discussed thoroughly whether or not to 
even put that code into Roxy. We ultimately did it to make developer lives 
easier by giving them better error messages. We figured the utility outweighed 
the hackery.
</obligatory-disclaimer>

Paxton Hare
Principal Community Engineer
MarkLogic Corporation<http://www.marklogic.com/>
http://developer.marklogic.com<http://developer.marklogic.com/>

From: 
<[email protected]<mailto:[email protected]>>
 on behalf of Rob Szkutak 
<[email protected]<mailto:[email protected]>>
Reply-To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Date: Wednesday, December 30, 2015 at 9:00 PM
To: MarkLogic Developer Discussion 
<[email protected]<mailto:[email protected]>>
Subject: Re: [MarkLogic Dev General] API to get the executing function name and 
the xquery file

Chris,

Nice find!

I was able to adapt this into a quick example that I hope everyone will find 
useful.

First, run this in query console. It will insert a "trace.xqy" module I made 
based off of reflection.xqy and a module to test it called "foo.xqy":


xquery version "1.0-ml";

xdmp:document-insert("/foo.xqy", document{'module namespace foo = 
"http://marklogic.com/foo";;

import module namespace trace = "http://marklogic.com/trace"; at "/trace.xqy";

declare function foo:foo()
{
  try
  {
    fn:error(xs:QName("boom"), "")
  }
  catch($e)
  {
    trace:getTrace()
  }
};'}),

xdmp:document-insert("/trace.xqy", document{'

(:
Copyright 2012-2015 MarkLogic Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
   http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
:)

module namespace trace = "http://marklogic.com/trace";; declare function 
trace:getTrace()
as map:map
{

let $trace := map:map()

let $PREVIOUS_LINE_FILE :=
  try {
   fn:error(xs:QName("boom"), "")
  }
  catch($ex) {
    map:put($trace, "previous_line_file", 
fn:concat($ex/error:stack/error:frame[3]/error:uri, " : Line ", 
$ex/error:stack/error:frame[3]/error:line))
  }

let $__LINE__ :=
  try {
   fn:error(xs:QName("boom"), "")
  }
  catch($ex) {
    map:put($trace, "line", $ex/error:stack/error:frame[2]/error:line)
  }

let $__FILE__ :=
  try {
   fn:error(xs:QName("boom"), "")
  }
  catch($ex) {
    map:put($trace, "file", ($ex/error:stack/error:frame[2]/error:uri, "no 
file")[1])
  }

let $__CALLER_FILE__ :=
  try {
   fn:error(xs:QName("boom"), "")
  }
  catch($ex) {
    map:put($trace, "caller_file", ($ex/error:stack/error:frame[3]/error:uri, 
"no file")[1])
  }

return $trace
};'});


Next, run this in query console to test it:

xquery version "1.0-ml";

import module namespace foo = "http://marklogic.com/foo"; at "/foo.xqy";

foo:foo()


It will return this output:

map <http://localhost:8000/qconsole/#>
<map:mapxmlns:map="http://marklogic.com/xdmp/map"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xs="http://www.w3.org/2001/XMLSchema";>
<map:entrykey="caller_file">
<map:valuexsi:type="xs:string">
no file
</map:value>
</map:entry>
<map:entrykey="line">
<map:value>
<error:linexmlns:error="http://marklogic.com/xdmp/error";>
13
</error:line>
</map:value>
</map:entry>
<map:entrykey="file">
<map:value>
<error:urixmlns:error="http://marklogic.com/xdmp/error";>
/foo.xqy
</error:uri>
</map:value>
</map:entry>
<map:entrykey="previous_line_file">
<map:valuexsi:type="xs:string">
: Line 5
</map:value>
</map:entry>
</map:map>


In practice, in your code, after importing the trace module, you could do 
something like this:

let $trace :=
try
  {
    fn:error(xs:QName("boom"), "")
  }
  catch($e)
  {
    trace:getTrace()
  }

And then you'd have a map stored in $trace with information about exactly where 
you are in your code.

Best,
Rob

Rob Szkutak
Associate Consultant
MarkLogic Corporation
[email protected]<mailto:[email protected]>
Cell +1.716.562.8464
www.marklogic.com<http://www.marklogic.com>

________________________________
From: 
[email protected]<mailto:[email protected]>
 
[[email protected]<mailto:[email protected]>]
 on behalf of Chris Grimes [[email protected]<mailto:[email protected]>]
Sent: Wednesday, December 30, 2015 7:07 PM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] API to get the executing function name and 
the xquery file

I have not used this code directly but it looks like it may be what you're 
after:

https://github.com/marklogic/roxy/blob/master/src/roxy/lib/reflection.xqy

Sent from Outlook Mobile<https://aka.ms/qtex0l>




On Wed, Dec 30, 2015 at 9:22 AM -0800, "Will Thompson" 
<[email protected]<mailto:[email protected]>> wrote:

None that I am aware of. I have seen this done, however, by throwing an 
exception in a try block, and using the catch block inspect the error XML to 
determine contextual information.

try {
  error((), 'BOGUS-ERROR')
} catch ($e)
{
  ** get context from $e **
}

-Will

> On Dec 30, 2015, at 1:30 AM, Tyagi, Devesh 
> <[email protected]<mailto:[email protected]>> wrote:
>
> Hi,
>
> Is there an API in Marklogic 7 which can give me the context which is 
> executing. For example if I have a module "sample.xqy" and a function 
> "sample:foo()" in it, I want the API to give me at least "sample:foo()".
>
> Regards,
> Devesh
> "This e-mail and any attachments transmitted with it are for the sole use of 
> the intended recipient(s) and may contain confidential , proprietary or 
> privileged information. If you are not the intended recipient, please contact 
> the sender by reply e-mail and destroy all copies of the original message. 
> Any unauthorized review, use, disclosure, dissemination, forwarding, printing 
> or copying of this e-mail or any action taken in reliance on this e-mail is 
> strictly prohibited and may be unlawful." 
> _______________________________________________
> General mailing list
> [email protected]<mailto:[email protected]>
> Manage your subscription at:
> http://developer.marklogic.com/mailman/listinfo/general

_______________________________________________
General mailing list
[email protected]<mailto:[email protected]>
Manage your subscription at:
http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
Manage your subscription at: 
http://developer.marklogic.com/mailman/listinfo/general

Reply via email to