JavaScript Catching exception from within function or object - javascript

I encountered quite annoying problem. I can't catch errors thrown from within the functions. And to be honest - I wouldn't care much if not the fact that the same applies for throwing errors from within the JavaScript Objects.
Here's the sample code:
http://jsfiddle.net/TxsHK/1/ (you'll need firebug console to test this code)
function ViewError($CONTENT){
this.content = $CONTENT;
return this.content;
};
try{
$(document).ready(function() {
//--------------
throw ViewError('Test error');
//--------------
});//$(document).ready(function() {
}catch (e) {
if (e instanceof ViewError) {
console.info(e.message);
}
else{
console.warn(e.message);
}
}
gives an error
TypeError: e is undefined
Why? The errors thrown by functions (or objects) should be perfectly catchable. That's the whole purpose of try - catch block: to catch exceptions out of functions. At least... so it is in other languages.
Anyone can explain what's going on? And how can I catch exceptions from within the functions / objects?

Your "ViewError" function doesn't return anything. You're therefore throwing undefined. (edit — your fiddle is diffferent from the posted code - don't do that!)
The "ViewError" function is being called in a way that I don't think to be correct, given the way the code is written. I think you want throw new ViewError("Test error"); in order to make sure a new object is created.
There's another problem: you're expecting that you'll be able to catch exceptions thrown from that call to $(document).ready(), but that's not necessarily going to work. If the document isn't ready yet when that code runs, then you'll get no exceptions because the call returns immediately. The function you pass in would be called later, when the document is ready.

Related

How can I avoid using nested try catch when working with onSnapshot?

this the first time I had to encounter a situation like this where a try catch block wasn't catching errors throwed inside onSnapshot , so I had to use a nested tryCatch block inside it did what I was expecting but it kind looks dirty . I was wondering if this is avoidable ,my code :
const fetchTodaysOrders =async (arg,state)=>{
try {
const fetchOrdersReponse = await firestore()
.collection('orders')
.where('distrubutorId','==',currentDistrubutorId)
.where('status','==','PENDING')
fetchOrdersReponse.onSnapshot(res=>{
const docs= res.docs
try {
if(docs && docs.length){
//some code ...
}else{
throw new Error('NO_DOCS')
}
} catch (error) {
console.log("----fetchTodaysSectors catch2------")
dispatch.scheduel.fetchTodaysSectorsFailed()
}
})
} catch (error) {
//this wasn't hit when the error was encountered
console.log("----fetchTodaysSectors catch1------")
dispatch.scheduel.fetchTodaysSectorsFailed()
}
}
You need to understand the Observer pattern properly. The function passed as parameter to onSnapshot does not get called immediately, but rather when the response comes back from firebase. Consequently the execution of the try block associated with 'catch1' completes before the call back function is executed.
There error is not thrown in the onSnapshot function, but rather in the callback function that gets called after results are returned. So handling it inside the callback function is in fact the right way to do it.
Also you are only using some parameters of the onSnapshot. Please consider going through reference and you might find better ways to deal with this. https://firebase.google.com/docs/reference/js/firebase.firestore.Query
Also if you want to deal with errors in a more elegant manner please consider using Rxjs in combination with firebase (https://www.learnrxjs.io/learn-rxjs/operators/error_handling/catch)

Should I catch errors in a function which calls just a function which already uses try and catch in its body?

I to have write a function that checks if a file is valid (exists & granted correct permissions), and other one that returns a valid filepath. These functions call the check file function which uses try catch.
Should my function validFilePath catch errors also?
No, you do not need to use try/catch in all circumstances.
If there is no code path that causes the function you're calling to throw, then you don't need to surround it with a try/catch. It is your responsibility as a programmer to know what the functions you call can do in terms of errors and to code to that. Do they return an error? Do they return null? Do they throw an exception? If they do not throw an exception because they already catch any possible exception, then there is no reason for the caller to surround the function call with a try/catch.
You do need to code for all possible return values, including error conditions.

Is there type of error in Javascript?

I would ask about java script error, is there type of error like php
or others,
example: In php we have notice, and Parse Error ..etc notice will not
be stop php execute, but parse will be stop execute php code
directly..
now is there js error like this, or what is the js classification
error .. I know we can handle error by try, catch ..,but is there
error in js was stooped script and others will not stop execute script
thank you
is there error in js was stooped script and others will not stop execute script
Not except for parsing/syntax errors, no.
JavaScript has exceptions. An exception exits the code in which it is thrown, and the code that called that, and so on until it's caught. If it isn't caught, then all currently-running functions are terminated and the error is logged to the web console.
So an exception (either one you throw explicitly or one that happens as a by-product of something you do) will either terminate all running functions (if not caught) or only terminate some code (if caught).
For example:
function foo() {
try {
bar(0);
}
catch (e) {
console.log("Caught exception");
}
}
function bar(a) {
if (a <= 0) {
throw new Error("'a' cannot be <= 0");
}
console.log("bar: a = " + a);
}
foo();
There, the code in bar following the exception is not run (we don't see "bar: a = 0") because an exception was throw, terminating bar. But foo's code continues, in the catch block, because foo caught the exception.
JavaScript is unusual in that you can throw anything, including a string, a number, etc. But if you want useful information, you usually throw Error:
throw new Error("Optional message here");
Since what you throw can be anything, you might be thinking there's a way to catch only certain things, but that's not the case. catch catches any exception that was thrown. So:
try {
throw "foo";
}
catch (e) {
}
try {
throw new Error();
}
catch (e)
}
try {
throw 42;
}
catch (e)
}
Note that those catch clauses are identical; they catch anything that was thrown. Of course, you can then inspect what you got and re-throw:
try {
// ...some code here that may throw any of several things...
}
catch (e)
if (typeof e === "string") {
// Handle it here
}
else {
throw e;
}
}
There we only handle exceptions that are strings, and not ones that are numbers, Error objects, etc.
You can create your own derived versions of Error if you like, although it's a bit more of a pain than it ought to be:
function MySpecificError(msg) {
this.message = msg;
try {
throw new Error();
}
catch (e) {
this.stack = e.stack;
}
}
MySpecificError.prototype = Object.create(Error.prototype);
MySpecificError.prototype.constructor = MySpecificError;
Then:
throw new MySpecificError("Something went wrong.");
Note that we had to fill in the code in MySpecificError to create the stack trace. (Also note that not all engines provide a stack trace, but if they do, this lets you use it.)
Some engines provide a few error types out of the box:
Error
RangeError (something was out of range)
ReferenceError (but usually that's something you'd let the engine throw)
TypeError (again)
SyntaxError (again)
Finally, it's worth noting that several things that would cause exceptions in other environments don't in JavaScript, mostly around math. For instance:
var result = 10 / 0;
In many non-JavaScript environments, that results in a runtime error (division by zero). In JavaScript, it doesn't; result gets the value Infinity.
Similarly:
var x = Number("I am not a number");
or
var x = parseInt("I am not a number", 10);
...doesn't throw a parsing error, it sets x to NaN ("not a number").
Yes. Javascript errors can have types, and there is a standard error type hierarchy. You can also write your code to "throw" things that are not error objects.
(In fact, since the catch clause in Javascript / ECMAScript does not discriminate based on the type of the exception, exception handling tends to be rather crude; i.e. "catch all errors" and then attempt to recover. Hence, to a first order, it doesn't matter what you throw.)
The ECMAScript 5.1 spec says that syntax errors are "early errors" and that they must be reported before the program is executed. An exception to this is syntax errors detected in code being run using eval. However, the spec doesn't say how early errors are to reported, or what happens afterwards. (At least, I don't think it does ...)
I believe that a common strategy for a Javascript parser/compiler/interpreter to skip to the enclosing block, and replace the affected code with code that throws an exception (e.g. SyntaxError) if it is run.
References:
http://www-archive.mozilla.org/js/language/js20-1999-02-18/error-recovery.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError
EcmaScript 5.1 - Errors

Uses of the finally statement

This is a very basic question. In Java I use the finally statement to close resources because "it's a good practice". I've been developing in Javascript and then in Node.js during some years and I've never used the finally statement. I know that in Node.js all of us follow the first parameter error handling pattern. Anyway, the 2 following snippets do the same:
try{
throw 123
}catch (e){
}finally{
console.log(1)
}
.
try{
throw 123
}catch (e){
}
console.log(1)
Both print 1.
Why is finally a keyword if it has no real benefit? The clean up code can be put inside the catch.
finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break.
Just a simple and straightforward example that shows the difference. There is a return that breaks the function completion, but the console.log in finally is called while the last console.log is skipped.
let letsTry = () => {
try {
// there is a SyntaxError
eval('alert("Hello world)');
} catch(error) {
console.error(error);
// break the function completion
return;
} finally {
console.log('finally')
}
// This line will never get executed
console.log('after try catch')
}
letsTry();
But try this:
try {
throw "foo"
} catch (e) {
throw "bar"
} finally {
console.log("baz")
}
console.log("quux")
If a second error is thrown from within the catch block, the code after the try...catch block will not run.
The finally block will always run, even if there is an error in the catch block.
Furthermore, the finally block runs even if a return or break statement stops the code in the try or catch block. return statements in the finally block override return statements in the try or catch block.
function foo() {
try {
return "bar";
} finally {
return "baz";
}
}
foo() // "baz"
oracle docs provide a good answer to this. Bottom line: finally gets called always! Even when you catch only one kind of exception (not the global catch), then finally gets called (after which your application probably breaks if there is no other catch)
the finally block is meant for a special purpose.
finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
Since it wont effect your business logic,Still it's compiler friendly,In memory aspects.
What if the try-block returns early or throws an exception that you don't handle? You would still want to free the resources you have allocated, right?
EDIT:
The answers to the question seem almost philosphical, there is some 'guessing' and basically 'we believe it should be useful, because it is there, so it should have a use', and 'even Oracle says so'. Or maybe it is there to help the programmer not 'to forget something' or 'accidently exit and not realize it'.
These are almost all valid reasons, but there is also a technical reason.
It helps avoiding code duplication in the cases mentioned, where (a) either the try or one of the catch blocks returns or (b) if within the catch block a second exception is thrown.
In these cases, if some cleanup code or any other code that still needs to be executed after the return and after the second exception, could be placed into the finally block, if it is to be executed both after the try and after the catch block.
You could still do it without the finally block, but the code would have to be duplicated, which the finally block allows you to avoid. This is where you really need it.
So if you are sure you do not miss it as a case of (a) or (b) you could still put the 'finally' code after the try/catch block and omit the finally clause.
But what if the situation changes? When you or another person change the code at some later point it could be forgotten to check if the cleanup code is now skipped in some situation.
So why not always put the cleanup code inside the finally block? And this is what is recommended and what many JavaScript programmers do.
You use it when you want to be sure your code is executed at the end, even if there was an exception during execution :
InputStream is = new FileInputStream("C://test.txt");
try {
//code...
} catch (Exception e) {
//code...
} finally {
is.close();
}
This is a very good question.
There is little to no reason to use finally in javascript, but I can imagine situations where it could be of practical use.
Suppose you have a webpage where you show a certain div after some user action, e.g. button clicked.
The div shows some logging for instance for the action the user requested.
After the action is complete (error or no error), you want to be sure to hide the div again. For that you can use the finally clause.
function doSomething() {
var d = document.getElementById("log");
show(d);
try {
... execute action ...
} catch(e) {
log(e);
} finally {
hide(d);
}
}
In general, as you mentioned, exceptions are less and less used in JavaScript in favor of error callbacks.
So, one could as well ask, what good uses are for exceptions in JavaScript in general.
The problem is with your example. There are cases when you don't want to catch the exception.
try {
if (Math.random() > 0.5) throw 123
}
finally {
console.log(1)
}
In these cases all you could do is rethrowing the exception if you don't want to use finally.
try {
if (Math.random() > 0.5) throw 123
}
catch (e) {
console.log(1)
throw e
}
console.log(1)
or maybe
try {
if (Math.random() > 0.5) throw 123
console.log(1)
}
catch (e) {
console.log(1)
throw e
}
Both alternative solutions lead to code duplication, that's why you need the finally keyword. It is used most of the time to free up unused resources. Forgetting about it may lead to unwanted locks or connections or memory leaks. I guess in some cases even a smart GC cannot prevent it.
In Java, if there's an Exception thrown that is not matched by any of the catch-blocks execution will break and any open resources will be left open.
The finally block will always be executed, even if an uncaught exception occurs.

Javascript error stops code execution

Whenever an error occurs inside an event handler, it stops code execution entirely so the second event callback isn't called.
For example:
$(function() {
window.thisDoesntExist();
}
$(function() {
//Do something unharmful and unrelated to the first event
}
You can easily solve the problem in this (simplified) example by adding try/catch in both anonymous functions, but in reality these functions often add several other event handlers which in turn would require try/catch. I end up with very repetitive code stuffed with try/catch blocks.
My projects has a modular design where each feature is in a different JS (and gets concatenated during a build process). I'm looking for a more generic way to handle errors inside each feature so that the error doesn't stop code execution of the other features.
I already tried following solutions:
- window.onerror (even if you return true in this function, code execution is stopped)
- $(window).error() => deprecated and code execution stops
You could create a helper function to prevent duplication of the same boilerplate code.
function tryFunction(f, onerror) {
try {
if (typeof f == 'function') {
return f();
}
} catch (e) {
return onerror(e);
}
}
$(function() {
var result = tryFunction(window.thisDoesNotExist, function (error) {
alert('Whoops: ' + error);
});
});
I created a little demonstration. It's slightly different but the same idea.
You can simply call if (typeof myFunction == 'function') before calling myFunction()
And optionally wrap it in a generic function like said by Bart to have the choice to log an error in the console if your function does not exists.
If your webapp is huge with many interaction and JS, too many try catch could alter the global performance of your application.
I would try something like this with a wrapper which will handle the try catch for you (see below, or this jsfiddle : http://jsfiddle.net/TVfCj/2/)
From the way I'm (not, and not really) handling the this and the arguments, I guess it's obvious I'm beginning with js. But I hope you get the idea, and it is correct/useful.
var wrapper = {
wrap: function wrap(f) {
return function (args) {
try {
f.apply(null, args);
} catch (ex){
console.log(f.name+" crashed with args "+args);
};
};
}
};
var f1 = function f1Crashes(arg) {
return window.thisDoesntExist();
};
var f2 = function f2Crashes(arg) {
return window.thisDoesntExist();
};
var f3 = function f3MustNotCrash(arg) {
wrapper.wrap(f1)(arg);
wrapper.wrap(f2)(arg);
}
f3('myarg');
The try-catch pattern you mention attempting in your question is the correct way - you want try-catch blocks, not a way to silently truck through module errors (in general always be extremely careful handling exceptions globally and continuing, that way lies data corruption bugs you only find 6 months later).
Your real problem is this:
... in reality these functions often add several other event handlers which in turn would require try/catch. I end up with very repetitive code stuffed with try/catch blocks.
The fix for that is Promise. This is a new structure, native in most browsers but easily shimmed in the slow ones (ahem, IE), that gives you a standard way of managing both the event callback and the exception from the event.
With a Promise your code makes a promise to always do something: either resolve/succeed or reject/fail.
function moduleA() {
return new Promise(function (resolve, reject)
{
try{
var result = window.thisDoesntExist();
resolve(resolve); // Success!
}
catch(err){
reject(err); // Fail!
}
});
}
This is better because rather than nest try-catch blocks in each callback you can instead chain promises:
moduleA().
then(moduleB).
then(moduleC).
catch(errorHandler); // Catch any error from A, B, or C
You can also handle an error and continue:
moduleA().
catch(continuableErrorHandler). // Catch any error from A
then(moduleB).
then(moduleC).
catch(errorHandler); // Catch any error from B or C
You'll still need lots of try-catch blocks in callbacks, but anything that has been wrapped in a Promise can be treated in the same modular way.
Coming next in JS is async and await, but you can use them now with a transpiler. These use promises to make code that is much easier to read, and most importantly (for you) have a single try-catch at the top that gathers exceptions from the entire Promise chain.
This answer is already too long, but I've blogged about that in more detail.
TL;DR: If your problem is "very repetitive [event callback] code stuffed with try/catch blocks" try using Promise instead.
I found a solution. When using setTimeout, the code is executed in a seperate thread, therefor it won't break any other parts of the webpage.
$(function() {
setTimeout(function() {
window.thisDoesntExist();
}, 0);
});
$(function() {
setTimeout(function() {
//Do something unharmful and unrelated to the first event
alert("This passes")
}, 0);
});
In this example, the second function is run, even when the first one throws an error.
Here's a working example: http://jsfiddle.net/mathieumaes/uaEsy/

Categories

Resources