How to show error log in a template in eXist-db, not outside of it? - exist-db

In the controller I have:
else if (ends-with($exist:resource, ".html")) then
(: the html page is run through view.xql to expand templates :)
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<view>
<forward url="{$exist:controller}/modules/view.xql">
<set-header name="Cache-Control" value="no-cache"/>
</forward>
</view>
<error-handler>
<forward url="{$exist:controller}/error-page.html" method="get"/>
<forward url="{$exist:controller}/modules/view.xql"/>
</error-handler>
</dispatch>
Typically, this helps when a templating function fails (like <div class="app:list-journals"/>). How to use that for any function failing on the background (e.g. after submission of a form)?
UPDATE
Here is the code where I am trying to catch the error of the templating function:
...
} catch * {
<error>Error {$err:code}: {$err:description}</error>
}
This does not work. The app still uses its own logs as bare XML responses.
Or I would expect this:
...
} catch * {
logger:add-log-message(concat('Error: ', $err:code, $err:description))
}
... could work with some redirecting to a global error page but it does not. As soon as the error is not the problem of the app but, let's say, of a XSLT process, it is not possible to redirect the app to some global page as described in the book by A. Retter (it is necessary to use $EXIST_HOME/webapp/WEB-INF/web.xml file and there to describe the error and the particular page for redirecting).
More information, no progress.

Well, this question is rather clumsy and the answer has to be a bit cumbersome. The problem is I was not aware of several things regarding to errors and their relationship with XQuery and eXist’s templating module.
It seems there are basically three levels of errors I can deal with on the surface:
1 — errors associated with templating
These errors are the easiest to solve. It is enough to define an error handler in your controller for URL rewriting (in general or for a particular page):
else if (ends-with($exist:resource, ".html")) then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<view>
<forward url="{$exist:controller}/modules/view.xql">
<set-header name="Cache-Control" value="no-cache"/>
</forward>
</view>
<error-handler>
<forward url="{$exist:controller}/error-page.html" method="get"/>
<forward url="{$exist:controller}/modules/view.xql"/>
</error-handler>
</dispatch>
If any function associated with templating fails, the log is showed inside a frame and it looks like a common part of your app page:
2 — errors associated with some special HTTP code via Jetty
These errors are logged by Jetty—the page disappears and instead of it there is usually a long log. It is possible to make a record of such an error in the $EXIST_HOME/webapp/WEB-INF/web.xml:
<error-page>
<error-code>404</error-code>
<location>/db/central/page404.xq</location>
</error-page>
The location should, logically, point to a real page inside of your app. And we can’t forget to its definition in our controller.xql:
else if ($exist:path eq 'error-404.html') then
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
<forward url="{$exist:controller}/errors/error-404.html"/>
<view>
<forward url="{$exist:controller}/modules/view.xql">
<set-header name="Cache-Control" value="no-cache"/>
</forward>
</view>
</dispatch>
This solution is useful if you know about repeating errors you want to make more friendly to users. Great for HTTP 404 or HTTP 500 errors. HTTP 500 errors are the biggest problem because the are associated with errors made by functions running. Nice solution.
3 — the rest
In XQuery, there are several types of errors. For dynamic errors (thrown during runtime and logged as HTTP 500 errors by Jetty) it is possible to use try/catch statements. With them, it’s possible to catch logs and to store them somewhere in your app. If you treat them like me in the number 2, it is enough. Other types of errors are (from my point of view) much harder to catch (static, typed and so on). This means there is no easy way how to hide them for users. The plus is you usually know about them earlier during prototyping and testing, anyway.
Maybe there is some complex possibility of showing all errors in a friendly way but it is outside of space and time of this forum. Inspiration is in Demo apps. Such a solution may be a bit time consuming and it’s a bit artificial problem at the moment.
Any clarifications and arguments are very appreciated.

Related

ColdFusion Proxy Server

I'm trying to create a basic proxy server so I can keep track of what my kids are doing web wise - I know there are products out there but I thought it would be an interesting exercise to write one myself.
I have the following code that kind of works but doesn't pull any images or css through - I guess because it makes another call to the remote server and gets confused
<cfhttp url="https://www.bbc.co.uk">
<cfhttpparam type="header" name="Proxy-Connection" value="keep-alive" >
<cfhttpparam type="header" name="Accept" value="application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5">
<cfhttpparam type="header" name="Accept-Language" value="en-US,en;q=0.8">
<cfhttpparam type="header" name="Accept-Charset" value="ISO-8859-1,utf-8;q=0.7,*;q=0.3">
</cfhttp>
<cfset html = cfhttp.FileContent />
<cfoutput>#html#</cfoutput>`
What am I missing?
What you want to use is the resolveurl parameter of - set it to yes/true. This defaults to no.
What this parameter does is resolves relative paths to absolute paths automatically for you.
Now, if you want to change those paths as well, you would change them to also route through your http proxy script, but there won't be much use as you won't know much about the content regardless.
resolveurl should hook you up with what you are looking for. cheers.
https://cfdocs.org/cfhttp (look for resolveurl tag attribute)

Drupal, entity_metadata_wrappers and debugging

For handling entities in Drupal I'm using Entity Metadata Wrappers (the "Drupal way").
It's really easy to start coding and see all the advantages it has... except when you get a fatal error and you are not clear where it comes from.
This is what the database log shows:
EntityMetadataWrapperException: Unknown data property
field_whatever. at EntityStructureWrapper->getPropertyInfo()
(line 335 of
/var/www/html/sites/all/modules/entity/includes/entity.wrapper.inc).
Sadly, many times that "field_whatever" is "nid", "uid" or some very common property, so it's name is spread all over my code, which makes me difficult to get to the origin of the error.
I'm currently doing this:
Write a tiny piece of code and then run to see if something fails.
Using getPropertyInfo when handling entities with "not so common" fields.
Loosing hair.
What is worst is that sometimes the error does not appear when you are coding, but a week later. So it could be anywhere...
Is there any way of handling entity metadata wrapper errors better? Can I get better information in the database log and not just a line? A backtrace maybe?
Thanks.
Well, having the devel module active (just to see the nice krumo message) we can do something like this inside our module:
<?php
set_exception_handler('exception_with_trace');
function exception_with_trace($e)
{
dpm($e->getTrace());
}
That will return the backtrace error of the exception thrown by the entity metadata handler on the next page load (some page in your site where everything is running fine).
Also you can set the exception handler exclusively and more elegant just for some pages or some users with some role... or when some parameter in the url is met, or when in some state of your Drupal site is met (ex. when a bool persistent variable 'exception_with_trace' is true). Even, under certain conditions and control, you can use it in production too.
If the site does not work "at all" you can include it in your settings.php file, but instead of printing the trace, you must write the trace to a file and watch the trace in a different context (not Drupal but some php file).
If exceptions are too long and are causing memory problems then getting the trace as string is also possible. See http://php.net/manual/es/exception.gettraceasstring.php
Hope that helps.

HtmlUnit thorw error "define is not defined"

I tried to load simple page using HTMLUnit it is throwing below error
Enclosed exception:
net.sourceforge.htmlunit.corejs.javascript.EcmaError: ReferenceError: "define" is not defined.
I think this is problem because of ECMA6 ? But I am not able to find any way to resolve
My first attempt would be to ignore all javascript related Exceptions because on most web sites the interesting parts work even if some of the javascript is not executed.
webClient.getOptions().setThrowExceptionOnScriptError(false); // we never want Exceptions because of javascript
Some other properties which are often useful (not directly related to your problem) are:
webClient.setJavaScriptTimeout(30000); // limit to e.g.30s
webClient.getOptions().setTimeout(300000); // timeout to e.g. 300s = 5min
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setPopupBlockerEnabled(true);
webClient.setRefreshHandler(new WaitingRefreshHandler(...)); // limit the time for refreshes

Can I use Serilog.Extra.Web's HttpRequestNumber or HttpRequestId as the SerilogMetrics timed-operation identifier?

I'm using SerilogMetrics's BeginTimedOperation() in a Web API, and it would be really great to be able to use the HttpRequestNumber or HttpRequestId properties (from the respective Serilog.Extra.Web enrichers) as the identifier, making it super easy to correlate timing-related log entries with others across a request.
Something like:
using (logger.BeginTimedOperation("doing some work", HttpRequestNumberEnricher.CurrentRequestNumber))
{ ... }
Short of poking around in HttpContext.Current for the magically- (i.e. non-public) named properties, is this achievable? Thanks!
If you begin a timed operation during a web request, the operation's events will already be tagged with the HttpRequestId.
You'll see it when logging to a structured log server like Seq, but if you're writing it out to a text file or trace then the property won't be included in the output message by default. To show it in there use something like:
.WriteTo.File(...,
outputTemplate: "{Timestamp} [{Level}] ({HttpRequestId}) {Message} ...")
The logging methods use a default template you can draw on for inspiration, and there's some info spread around the wiki though there's no definitive reference.

ClientGlobalContext.js.aspx broken in Dynamics 2011?

I am trying to implement a custom web resource using jquery/ajax and odata. I ran into trouble and eventually found that when I call:
var serverUrl = context.getServerUrl();
The code throws exceptions.
However, when I change serverUrl to the literal url, it works. I then found forum posts that said I should verify my .aspx page manually by going to https://[org url]//WebResources/ClientGlobalContext.js.aspx to verify that it is working. When I did that I received a warning page:
The XML page cannot be displayed
Cannot view XML input using style sheet. Please correct the error and then click the Refresh button, or try again later.
--------------------------------------------------------------------------------
Invalid at the top level of the document. Error processing resource 'https://[org url]//WebResources/Clien...
document.write('<script type="text/javascript" src="'+'\x26\x2347\x3b_common\x26\x2347\x3bglobal.ashx\x26\x2363\x3bver\x2...
What the heck does that mean?
Hard to tell outside of context (pun not intended) of your code, but why aren't you doing this?
var serverUrl = Xrm.Page.context.getServerUrl();
(Presumably, because you have defined your own context var?)
Also, this method is deprecated as of Rollup 12, see here: http://msdn.microsoft.com/en-us/library/d7d0b052-abca-4f81-9b86-0b9dc5e62a66. You can now use getClientUrl instead.
I now it is late but hope this will be useful for other people who will face this problem.
Until nowadays even with R15 there are two available ClientGlobalContext.js.aspx
https://[org url]/WebResources/ClientGlobalContext.js.aspx (the bad one)
https://[org url]/[organization name]/[publication id]/WebResources/ClientGlobalContext.js.aspx (The good one)
I don't know why exist 1. but it causes many issues like:
It could not be published or hold information (Your case #Steve).
In a deployment with multiple organizations, seems it saves info only for the last organization deployed causing that methods under Xrm.Page.context. will return info from a fixed organization. Actually each method that underground uses these constants included in ClientGlobalContext.js.aspx: USER_GUID, ORG_LANGUAGE_CODE, ORG_UNIQUE_NAME, SERVER_URL, USER_LANGUAGE_CODE, USER_ROLES, CRM2007_WEBSERVICE_NS, CRM2007_CORETYPES_NS, AUTHENTICATION_TYPE, CURRENT_THEME_TYPE, CURRENT_WEB_THEME, IS_OUTLOOK_CLIENT, IS_OUTLOOK_LAPTOP_CLIENT, IS_OUTLOOK_14_CLIENT, IS_ONLINE, LOCID_UNRECOGNIZE_DOTC, EDIT_PRELOAD, WEB_SERVER_HOST, WEB_SERVER_PORT, IS_PATHBASEDURLS, LOCID_UNRECOGNIZE_DOTC, EDIT_PRELOAD, WEB_RESOURCE_ORG_VERSION_NUMBER, YAMMER_IS_INSTALLED, YAMMER_IS_CONFIGURED_FOR_ORG, YAMMER_APP_ID, YAMMER_NETWORK_NAME, YAMMER_GROUP_ID, YAMMER_TOKEN_EXPIRED, YAMMER_IS_CONFIGURED_FOR_USER, YAMMER_HAS_CONFIGURE_PRIVILEGE, YAMMER_POST_METHOD. For instance method Xrm.Page.context.getUserId() is implemented as return window.USER_GUID;
To be sure that your URL is the correct just follow the link posted by #Chris

Resources