Run time error handling on lazy loaded javascript? - javascript

Does anyone have any ideas how to do error handling on lazy loaded javascript? I am using an approach in which an ajax request is called and the code is eval'd in global scope. When a runtime error is struck, it spits out the filename as my lazy loading script and the line number is the error line plus the line number of my eval in my loading script. This wouldn't be so bad except all the javascript files get combined into modules for sections of the site. A try catch around the javascript file itself wont catch runtime errors of the functions. Any ideas? Window.onerror doesn't provide the correct filename so it is out of the question. I need to catch it before it is hit.
I was thinking maybe I could programmatically include try catches around all the functions within the eval'd code (which is ugly), but since it is done at the window level I am not sure how to access the eval'd code specifically and dynamically. Sure if the javascript is an object named "Bob" I can access window.Bob but I need to do it dynamically.

I solved the issue, however it is not the most elegant solution. Essentially what I do is this:
1. After the site loads I look at all the objects that are in window and push them into an array. This basically says to my code, ignore these objects.
When I modularize my code I keep track of the length of the files and fileNames being place into a module.
The last line of the modulizer takes the fileLength array and lineLengths and calls a function in my error handling object;
The error handling code finds new objects in window. If they exist, set a property to match fileLengths and fileNames;
Recurse through the new objects and add decorate the functions to have try catches around them.
When one of those catches is hit, traverse upward and find the properties.
Calculate the file and line number based on the properties.
Output the new error based on the correct file and line number;
Yes ugly... but it works.

Related

Uncaught ReferenceError:some_string is not defined

In controller class, I have added
model.addObject("hostname", hostname);
and tried to catch it in my jsp page with
var hostname=<%=request.getAttribute("hostname")%> ;
Yet, this is throwing error
Uncaught ReferenceError:**some_string** is not defined
What can be done to avoid this?
Remember: You are not passing a variable from one program to another, you are programmatically generating JavaScript source code from JSP.
some_string is a variable name, but not one you've declared, so you get a ReferenceError.
You need to generate the JS source code which gives you the result you need.
For most cases, due to the compatibility between JS and JSON, you can use a JSON stringifier to generate the source code that creates your values (this is a good generic solution as it will do The Right Thing with quotes, new lines, arrays, etc).
Be careful as if the string contains </script> you need to escape the / to prevent it terminating the <script> element. Some JSON serializers will do this by default. I don't know if Java's will.

How to fix 'thrown exception caught locally' when using instanceof to determine internal errors type

I have a block of code that loads a set of plugins. For each plugin, a list of functions is called inside of a try catch block to determine if the plugin has failed or not and act accordingly. At the same time, one of the multiple functions of the plugin can return a specific error that mean that the plugin has not failed but is not valid to execute the next functions with the data.
Let's see an example (the code is Typescript, but I am going to make it as language agnostic as possible):
for each plugin:
try:
plugin.function1(data)
plugin.function2(data)
plugin.function3(data)
try:
plugin.function4(data)
catch error:
if error instanceof PluginNotValidForThisKindOfDataError:
continue
else:
throw error
plugin.function5(data)
plugin.function6(data)
catch error:
log(plugin has failed)
(I hope the code is clear enough. I'll update it if required)
As can be seen, I execute function4 and I parse the possible errors because one of them (there are multiple) is "tolerable" and just means that it is not valid for function5 and function6 with that specific set of data. However, I still have to throw the other errors because they are not good. At the end, I catch the global set of errors to determine if the plugin has crashed or not.
What I get in my IDE, JetBrains (WebStorm specifically) is a thrown exception caught locally warning. But I am not able to reimagine how to redo that block to act differently. I am not using throws as flow control but just passing the error.
I admit that the main problem is that in Javascript I can not do catch PluginNotValidForThisKindOfDataError, which would be the optimal situation (hope its added some day). But, with the tools I have, how can I refactor this?
Thank you very much.
Added to both language-agnostic and javascript because of the specific Javascript try-catch method
I see three options:
Ideally, the plugin wouldn't throw an error for a non-error condition like that. Instead, have it return a value that tells the code in your question whether it should run functions 5 and 6.
If you want to keep it the way it is, though, you can either:
Ignore the warning (and probably there's a way to disable it for one line), or
Don't re-throw; instead, do the same thing you're doing in the outer catch (log(plugin has failed)) followed by continue. Provided that's just a single function call or similar, the duplication isn't ideal, but isn't horrible either. If there's any complexity to that step, isolate it into a function (perhaps even a local function) and call that from both places.

javascript determine function definition line number

This question is about determining the line number of the function >definition<
in its source file. Just to be clear:
It is NOT about determining the line number of a caller - been there, done that. It is NOT about determining the CURRENT line number - been there, done that. It is NOT about examining the source code for the function - been there, done that. It is NOT about finding the name/url of the file when a break occurs and the line number in that file of the offender at that time - been there done that. It is NOT about using Chrome/Firefox/DragonFly Dev Tools to locate the offender. It is NOT about PHP, etc. Original source code can not be modified - only the exception handler (or the constructor which is being passed the function/anonymous function).
Context - the code is already in a [dump information routine called from a] catch block. I am trying to dump the specific offending line.
I have the offending line number in the source file; I have the offending function's code parsed into lines/line numbers. Thus I have the offset INTO the function (which is often an anonymous function). If I can somehow determine the line number where a function was defined (without forcing another exception), then the offset allows me to dump the offending line.
But the rub is getting the origin from which to compute the offset into
the function.
Possibilities of execution context for determining this include:
1) when the (anonymous) function is referenced/defined as part of a constructor (note: referenced/defined, NOT called) - at which time, if the line number of the >definition< in its source can be determined, it can be saved in the object
being constructed and then used later in the exception handler.
2) in the exception handler.
Sorry about the verbiage, but there are a lot of answers out there which seemingly (via search heuristics) address this, but in fact, none of them address the specific problem here.
Any suggestions, any at all, or is this hunting for a unicorn?
Thx (1138)
There's nothing in the information available within a catch block that will tell you what line in the source file the function containing that catch block starts on. I'm afraid you are indeed hunting for a unicorn.
You could use a pre-processor on the code that would add that information for you, using a parser like Esprima or by writing yourself a Babel plugin to do it. They have access to the necessary semantic and textual information to inject the number of the source line starting the function into the call to your "dump information" function.

What's the best way to handle Eclipse errors on CouchDB Map/Reduce JavaScript functions?

As noted in Where to write and store mongoDB map/reduce functions in java project - Eclipse doesn't like a JavaScript (.js) file to only contain the following:
function(doc) {
if(doc.somekey) emit(doc._id, doc);
}
The keyword function is marked with an error:
Syntax error on token "function", Identifier expected after this token
This form is used in MapReduce, but perhaps it's not exactly valid JavaScript (I'm not a lawyer). Is there any way to allow this form?
edit it looks like it's a function expression instead of a function statement. ( MDN, ECMA-262 )
Non-solution: "Just add a function name" according to https://stackoverflow.com/a/11258388/185799 it seems that it's not important to economize on the size of these functions. However, adding a function name results in: {"error":"compilation_error","reason":"Compilation of the map function in the 'myView' view failed: Expression does not eval to a function."}
Possible solution? Add a function name or "module.exports = " at the top, and then remove it during a build phase, using grunt/gulp/yeoman or something related.
For now, what I am actually doing is using the literal form function anonymous(... and then doing a string replace just before calling synchronizeWithDb() to replace function anonymous( with function(. This doesn't answer my question, but works around it.
You have three bad options:
You can ignore the error since CouchDB can process this file (it will wrap it later to make it valid).
You can change the file extension but then you lose syntax highlight, code completion and error checks.
You can delete the error in the error view. It will stay deleted until you change the file the next time or you do a full build.
You may be able to configure Eclipse to stop validating the file.
There are two ways to implement #4:
You can ignore the resource. That makes this file invisible to Eclipse and all plugins. Which means you can't edit it anymore inside of Eclipse. Use Resource Filters for that.
You can check the per-project preferences for Validation rules for JavaScript. Maybe you can exclude the file.

How to find the location of an error when line numbers cannot be used

I am finding it difficult to locate where an error occurs in javascript on a client I have no access to. Currently I trap the error with onerror and send the arguments to a log on the server.
Unfortunately the line number is no help because numerous javascript files get included, causing the line number to not correspond to anything I have access to.
So if I get something like "n is not defined", and n occurs many times in the function, I have no way to locate where it happened.
I have been trying to reference the code on the line throwing the error say "x=n * 5 + 4", then I could search for that code, but have had no luck referencing the actual code on a line from within javascript.
So how does one locate the line that threw the error in this situation?
client uses firefox only, if that matters.
I have no access to client
This is not one error I am stuck on, but working on how to track an error in this situation
Your best bet would be to use Firefox's debugger.
Open dev tools
Go to the debugger, select the .js file you want, and hit the little {} button in the bottom left (depending on version yours may be in a different location) -- this will prettify the JavaScript
Set breakpoints by clicking next to line numbers
From here on out you have to do this old-fashioned. Cast a breakpoint net around your trouble code, then keep narrowing down the lines until you find the occurrence that causes the error.
Of course, once you find the line it still won't be 1-to-1 with the original code, but hopefully the breakpoint exercise will at least reduce the scope of code/logic you have to dig through.
use your debugger to enable breaking on error. once you break, look at your locals for clues about your location. go up the stack and look at each frame.
you should be able to trace n up the stack and find out why it was null
the little {} that william suggested is also helpful

Categories

Resources