Hi France, Ok I get it now. No, really, because what your working on is very similar to what I'm regularly dealing with at work (translation, xliff etc.). I can also relate to your feeling that you need more control or insight in what's going on in your code. I have been through this journey too and sometimes I still find myself in a similar spot as you describe. Especially when deadlines are breathing in your neck ;-)
But I think that instead of looking for "technical" solutions to insert more logging to see what's going on what you need is to break up your code, bring more structure to it. There are many things going on in this small piece of code.For starters each "case" warrants a separate function. A function should be more or less about one thing (Single Responsibility Principle). Doing this will also make the code more testable. You can test each function separately. I admit this is not always easy but it is key to keep your code under control. Also have a look at the Unit module which provides you with a way to test each individual function with all types of arguments. You can run it very easily from the commandline (e.g. basex -t test-files/). During development of code immediately write these tests. You can even adopt a bit of test driven design (TDD) where you write tests even before the code works. Then you code until your tests pass. Best of all, you will keep these tests for the lifetime of your code and running them and seeing all of them pass will give you confidence in your code (or find out that you broke something). These test cases are also great documentation because they remind you of what a function was supposed to do when you already forgot because you went on to other projects. Another tip: when tackling something new and I'm not sure what combination of XQuery functions I need I always start the GUI, load the modules I'm working on and start experimenting. But once I have a better idea I start writing tests. It's not easy but very rewarding (and writing tests after the fact can feel very boring that's why you should do it while you work on the code). Every time I neglect these principles, because, for example, a deadline is near, it comes back to bite me later. In many cases it resulted in throwing away the code and starting from scratch. Sorry, no instant gratification by pointing you to a "magic" module. Still, I hope it helps you. Cheers, --Marc On Tue, Aug 19, 2014 at 11:12 PM, Andy Bunce <bunce.a...@gmail.com> wrote: > If the goal is debugging > .. another approach might be to think about Aspect Oriented Programming > something like > http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/ > > /Andy > > > On 19 August 2014 18:05, France Baril <france.ba...@architextus.com> wrote: >> >> Hi, >> >> I am hoping to use this for debugging. Our project is fairly complex and I >> use a controller function to apply multiple operations to content (each of >> these may use one or more function). When I get a 500 error, it's very hard >> for me to pinpoint the source of the issue. >> >> I can get the data from the form filled by the user and a few of the >> redirect, but that only gets me so far, if I could track both the function >> names and the parameters for sub-functions, it would save me a lot of time. >> >> Below is an example of what I call a controller... I use those when I need >> content to be saved before I can query it again for the next updating >> operation. Each if the workflow step uses multiple sub functions that are >> not accessed through http and that are as far as I know untraceable. >> >> (: Transforms content to xliff for each language and export packages for >> translation vendors :) >> >> declare %rest:path('/translation/create-package') >> %rest:GET >> %rest:query-param('menu-id', '{$menu-id}', '') >> %rest:query-param('lang', '{$lang-in}', '') >> (: The step that we were at when the function was called :) >> %rest:query-param('step-id', '{$step-id}', '0') >> %rest:query-param('package-number-in', '{$package-number-in}', '') >> %output:method("html") >> %output:html-version("5.0") >> updating function translation:create-package-controller($menu-id as >> xs:string, $lang-in as xs:string*, >> $package-number-in as xs:string, $step-id as >> xs:string){ >> >> >> ... >> >> let $workflow := <steps> >> <step id="1" name="Add-ids">Add @ids for >> en-us</step> >> <step id="2" name="Health-check">DB health check >> for en-us</step> >> <!--step id="3" name="Check-keywords">Check for >> keywords that may need to be replaced by prompts</step--> >> <step id="3" name="Process-to-xliff">Process files >> to skeletons and xliff</step> >> <step id="4" name="Register-packages">Register new >> packages in translation-management.xml... before deleting files with no new >> segments.</step> >> <step id="5" name="Old-content-to-target">Process >> files in no-new-segment (could have different attributes or deleted content) >> to target lang.</step> >> <step id="6" name="Delete-no-new-segment">Deletes >> no-new-segment xliffs that were processed in step >> Old-content-to-target.</step> >> <step id="7" name="Set-target-status">Sets >> updatibility of target topic</step> >> <step id="8" name="Export-and-zip">Export and zip >> files</step> >> </steps> >> >> >> ... >> >> >> switch ($workflow//step[@id=$this-step]/data(@name)) >> case 'Add-ids' return (:let $debug := >> file:append('debug-create-pack-crash.xml', ' In Add-ids '):) >> let $t := '' >> return (admin:add-ids('en-us'), >> >> db:output($next-step-forward)) >> >> ... >> >> >> case 'Set-target-status' return (:let $debug := >> file:append('debug-create-pack-crash.xml', ' In >> Set-target-status '):) let $t := '' >> >> return (for $lg in $lang >> return translation:toggle-target-status($lg), db:output($next-step-forward)) >> >> >> >> .... >> >> >> >> case 'Export-and-zip' return (let $zip := >> translation:export-and-zip($menu-id, $lang, $package-number) >> (:let $debug := >> file:append('debug-create-pack-crash.xml', ' In Export-and-zip '):) >> return ((), >> >> db:output($next-step-forward)) >> ) >> default return ((), >> db:output(admin:display-in-dashboard(<div><div class="l2" >> style="color:red;">An error has occured, you should have been redirected to >> the export function before reaching this point. Default in switch >> steps.</div>{app:get-beep-div-for-dashboard('error')}</div>))) >> >> >> }; >> >> >> >> >> On Tue, Aug 19, 2014 at 10:26 AM, Christian Grün >> <christian.gr...@gmail.com> wrote: >>> >>> Hi France, >>> >>> I would also be interested if you'd like a functionality as proposed >>> by Andy, and if you are interested in improving debugging your XQuery >>> code, or if you think that such a function could also be helpful in >>> productive code? Do you have some more input? >>> >>> Thanks, >>> Christian >>> >>> >>> On Mon, Aug 18, 2014 at 7:14 PM, France Baril >>> <france.ba...@architextus.com> wrote: >>> > Hi, >>> > >>> > I'm working on improving our tracking capabilities. I was hoping to >>> > find a >>> > function that would do the equivalent of what the code bellow does, but >>> > for >>> > internal functions that are not called through the rest interface. >>> > >>> > string-join(for $name in request:parameter-names() >>> > return $name || ': ' >>> > || string-join(request:parameter($name), >>> > '; '), >>> > >>> > ' ') >>> > >>> > In short, I was wondering if there is way I can read the function's >>> > parameters and their values without listing each one explicitly. >>> > >>> > I searched the documentation without success. >>> > >>> > -- >>> > France Baril >>> > Architecte documentaire / Documentation architect >>> > france.ba...@architextus.com >> >> >> >> >> -- >> France Baril >> Architecte documentaire / Documentation architect >> france.ba...@architextus.com > > -- --Marc