This question already has answers here:
What is the point of finally in a try catch/except finally statement
(5 answers)
Closed 5 months ago.
Is there any reason to put code in a finally block as opposed to just having code after the try...catch statement. Surely in both cases the code gets run anyway
try {
something();
} catch (error) {
error_handling_with(error);
}
// code here gets executed whether in finally clause or not.
finally_something();
Is there any place where finally is essential after try...catch? I can see it has a use in Promises, just not here.
finally basically runs even if you have an early-return from try-catch or even if you don't handle the error in the try-catch. Here is an example I like:
function myFunction() {
try {
console.log('inside "try"');
return
} finally {
console.log('inside "finally"');
}
console.log("after try-finally");
}
myFunction()
When you run myFunction(), it will print the following:
inside "try"
inside "finally"
Since you returned from try, it didn't execute any instructions after the try-finally block. But, Javascript did execute the finally block.
I think you have received the correct technical answer for this. However, if you are asking for practical usage, one situation is when you want to close a connection in any case. Here is a pseudo-code to explain:
openConnection();
try {
DoSomething();
return;
} catch (anomaly) {
handleAnomaly();
} finally {
closeConnection();
}
See in the above case, you close the connection in every case whether there is a handled exception, un-handled exception or happy flow, your connection will be closed and that too without duplication of code.
Catch/Finally are optional, the only rule is that 1 of them must always exist.
Finally exists so that code can always be run, disregarding whether or not an error was caught or not.
I would argue that in some cases they are added when they're not needed, but it helps readability, in other cases it might just be a habit.
Thies are example codes in MDN web docs to explain the important of finally block and it behaviour.
openMyFile();
try {
// tie up a resource
writeMyFile(theData);
} finally {
closeMyFile(); // always close the resource
}
Accordig to the MDN documentation finally execute no matter what the logic fail or not inside the try block.
In most cases inside a function there are code blocks must execute before workflow end.
Ex: no matter what if file is get opened it must close before exit from workflow.
function doIt() {
try {
return 1;
} finally {
return 2;
}
}
doIt(); // returns 2
In above code whether it should return 1. It will return 2 because it guarantee the execution of code inside finally block.But according to MDN this is a bad implementation.
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
Related
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)
Why don't people write all their JS code inside one big try...catch block? Or even better, tart all your code in one function and initiate your program by calling that function form a try...catch block. Why isn't this the norm? What is the catch?
function allMyJSCode() {
console.log("I can get here");
foo.bar = ""; //accessing property of uninitialized object
console.log("but never here");
}
try {
allMyJSCode();
} catch(error) {
console.log("Error from allMyJSCode: " + error);
}
//I can get here
//Error from allMyJSCode: ReferenceError: foo is not defined
Because once an error occurs, the rest of the code won't be executed, it will go directly to the catch block and ignore code that could be important. You don't want that.
Imagine this scenario:
// Important code #1
// Important code #2
Now, if you group these two together in one giant try...catch and for some reason Important code #1 throws an error then Important code #2 will never be executed and could cause problems, whereas if each of these where wrapped in their own try...catch, then no matter what happens in Important code #1, Important code #2 will be reached and get executed.
Important code #1 could be as trivial as changing the background of an element, and it could prevent the execution of code that handles populating data, sending requests, ...
Newbie to Node.js here. I'm learning Node.js via the tutorials at NodeSchool.io, and in one tutorial where we learned about modules, we were required to write something like this code:
// Some code...
function filteredLs(dir, ext, callback) {
fs.readdir(dir, function(err, files) {
if (err)
return callback(err); // return statement necessary here...
callback(null, withExtension(files, ext)); // ...but not here
})
}
module.exports = filteredLs;
My question is, in examples like these, why is it necessary to include the return statement when handling the error, but OK to omit when it's null? I don't see what use the return value of the function could have to readdir anyhow, since it happens after it finishes its work. Why does it make a difference?
The use of return when calling a callback function is typically there to prevent the code that follows from running. The returned value is typically irrelevant.
That's why it's needed in the error case, so the callback call for the non-error case isn't also called.
It's not needed in the non-error case because it's already the last line of the function.
The error handling boilerplate you posted is indeed confusing. It uses a maximally-terse way of expressing the code, but is indeed confusing, and you are right that the return value is discarded. Thus my preferred boilerplate for clarity is
if (error) {
callback(error)
return
}
Which I feel is slightly clearer and the reduced concision is not that important to me (I type it with a macro anway).
I find this to make it clearer that there are 2 distinct intentions being expressed here:
Bubble the error back up to the caller
Exit the function as there's nothing else useful to be done. No return value because the callback protocol does not require one and the calling code does not need to and probably will not even capture the return value into a variable.
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.
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/