How often do you use Try/Catch blocks in your JS code?
exception - Understanding try..catch in Javascript - Stack Overflow
Handling specific errors in JavaScript (think exceptions) - Stack Overflow
Javascript error handling with try .. catch .. finally - Stack Overflow
Videos
Hello,
I am taking a udemy course on JavaScript. In the Catching and Throwing Errors lesson, the teacher introduces us to Try/Catch block. My first remark was, why would someone write an alternative if his code didn't work while he supposed to find the source of the problem. When I searched in Stackoverflow and Quora, they almost agreed on the rule of 'use as less as possible'. And because of that, I'm wondering, How often do you use in real world projects?
Thank you so much!
I think your main problem is that you're swallowing exceptions, which is very bad. This is why "it works sometimes". Something is throwing an exception, and you're catching it, but then you're not doing anything else after that. At the very least I would display some sort of error message in your catch block.
A few other problems:
- Are you sure you need those multiple
try..catchblocks? The current assumption in your code is that each line that is wrapped in atry..catchis independent of the others, and execution can still proceed if something goes wrong in any one (or more) of those statements. Are you sure this is what you want? If so, there is definitely a better way of handling this. - If the statements are not independent of each other, and if a failure at any point means that execution cannot proceed, then you can wrap all of those statements in a single
try..catchblock and display an error message in thecatch - Like I said before, swallowing exceptions is very bad! You're hiding the problem and not achieving anything. It also makes debugging extremely hard, because things will stop working and you will have no idea why (no exception, no logging, no error messages). Exceptions are used when something unexpected happens that interrupts normal program flow. It is something you definitely want to handle.
I think what you want can be done this way:
try {
if(window.opener.hideRecordReload){
window.opener.hideRecordReload(pg.recordID, pg.recordTypeID);
} else {
window.opener.pg.hideRecord(pg.recordID, pg.recordTypeID);
}
window.opener.pg.hideEncounter(pg.recordID);
window.opener.pg.hideRecordResponse(pg.hideReasonID.value == 0 ? pg.otherReason.value : pg.hideReasonID.options[pg.hideReasonID.selectedIndex].text);
window.opener.pg.hideRecord_Response(pg.recordID, pg.recordTypeID);
window.opener.pg.hideRecord_Response(pg.recordID, pg.recordTypeID);
window.opener.window.parent.frames[1].pg.loadQualityMeasureRequest();
window.opener.pg.closeWindow();
}
catch(e) {
console.log(e);
}
This way, if an exception occurs anywhere along those series of statements, the catch block will handle it.
Javascript also doesn't have true checked-exceptions. You can get around it by having a single try block, and inspecting the exception object that you receive*.
Expanding on what I talked about earlier, there are two ways of handling exceptions. The first way, like I showed earlier, assumes that when an exception happens, the code is in an invalid/undefined state and this therefore means that the code encountered an unrecoverable error. Another way of handling exceptions is if you know it is something you can recover from. You can do this with a flag. So:
try {
doSomething();
}
catch(e) {
error = true;
}
if(error) {
doStuffToRecoverFromError();
}
else {
doOtherStuff();
}
In this case the flow of your logic depends on an exception being thrown. The important thing is that the exception is recoverable, and depending on whether it was thrown or not, you do different things.
*Here is a somewhat contrived example that demonstrates checked-exceptions. I have two exceptions called VeryBadException and ReallyBadException that can be thrown (randomly) from two functions. The catch block handles the exception and figures out what type of exception it is by using the instanceof operator):
function VeryBadException(message) {
this.message = message;
}
function ReallyBadException(message) {
this.message = message;
}
function foo() {
var r = Math.floor(Math.random() * 4);
if(r == 2) {
throw new VeryBadException("Something very bad happened!");
}
}
function bar() {
var r = Math.floor(Math.random() * 4);
if(r == 1) {
throw new ReallyBadException("Something REALLY bad happened!");
}
}
try {
foo();
bar();
}
catch(e) {
if(e instanceof VeryBadException) {
console.log(e.message);
}
else if(e instanceof ReallyBadException) {
console.log(e.message);
}
}
It's good practice do something with the caught exceptions.
What's happening here is that if there's an error (say loading a page fails) an exception is thrown inside one of your try blocks. The corresponding catch block grabs it and says "that exception has been dealt with" but in actuality you've not done anything with it.
Try putting a print(e.Message); inside your catch blocks to find out exactly what error is causing the page not to load and then add code to your catch block to deal with this error.
To create custom exceptions, you can inherit from the Error object:
function SpecificError () {
}
SpecificError.prototype = new Error();
// ...
try {
throw new SpecificError;
} catch (e) {
if (e instanceof SpecificError) {
// specific error
} else {
throw e; // let others bubble up
}
}
A minimalistic approach, without inheriting from Error, could be throwing a simple object having a name and a message properties:
function throwSpecificError() {
throw {
name: 'SpecificError',
message: 'SpecificError occurred!'
};
}
// ...
try {
throwSpecificError();
} catch (e) {
if (e.name == 'SpecificError') {
// specific error
} else {
throw e; // let others bubble up
}
}
As noted in the comments below this is Mozilla specific, but you can use 'conditional catch' blocks. e.g.:
try {
...
throwSpecificError();
...
}
catch (e if e.sender === "specific") {
specificHandler(e);
}
catch (e if e.sender === "unspecific") {
unspecificHandler(e);
}
catch (e) {
// don't know what to do
throw e;
}
This gives something more akin to typed exception handling used in Java, at least syntactically.
The finally block contains statements to execute after the try and catch blocks execute but before the statements following the try...catch statement. The finally block executes whether or not an exception is thrown. If an exception is thrown, the statements in the finally block execute even if no catch block handles the exception. more
The finally block will always run, try returning true after your try block
function myFunc() {
try {
if (true) {
throw "An error";
}
return true;
} catch (e) {
alert (e);
return false;
} finally {
//do cleanup, etc here
}
}
Finally blocks execute when you leave the try block. In your code this happens when you return false. That sets the return value to false and attempts to exit the function. But first it has to exit the try block which triggers the finally and overwrites the return value to true.
It is considered by many to be a good programming practice to have a single return statement per function. Consider making a var retval at the beginning of your function and setting it to true or false as appropriate throughout your function and then structuring the code so that it falls correctly through to a single return at the bottom.
I feel like I understand JavaScript quite well but I've never been able to grasp why I would use try/catch in any script that I write.
Any time I'd like to investigate anything in my script I just use the console and always seem to figure things out pretty quickly since the developer tools tend to show me exactly what went wrong and at what line. So what does try/catch have to offer?
I've looked into try/catch and it seems to just allow me to print a customized error message on the screen rather than the console using whatever script I write in the block and the catch argument. Ok.
How would this be useful? This seems mostly useless.
So I write custom error messages in my document window rather than just viewing them in my console. Why would I even want to do that? If I want to know basically anything and everything about a particular error it just shows up in the console.
I have yet to read a site that even explains why I would want to use this I only find sites that tell me how to do it. Can anyone clarify this for me? Thanks.
There are two primary problems with that code:
You have a typo:
var myErro = err;is missing theron the end ofmyErro.You're trying to use
errin thefinallyblock, but it's only in scope in thecatchblock.
...and then a few more that don't match what it seems like the assignment is telling you to do
You're not doing #1, you're doing something else which coincidentally also tries to use
myVarYou don't have any code implementing #6.
Your code assigning
resultwhen there's an error is puttingmyErrorNameandmyErrorMessageliterally in the string, rather than using the values of those variables.Your message for when no errors have occurred is not the same as the message they told you to use, it has slight differences (including a typo). Programming is at least partially about attention to detail. :-)
You don't need if (myError == err), just if (myError) will do:
try{
myVar();
}
catch(err){
var myError = err;
var myErrorName = err.name;
var myErrorMessage = err.message;
}
finally{
if(myError){
var result = "There was an error (myErrorName:myErrorMessage)";
console.log(result);
}else{
console.log("No error ocurred");
}
}
(I added a console.log so we'd see the error case.)
I've only addressed #1 and #2 in the above, the rest are left as an exercise for you to complete. :-)
I should note that I wouldn't write it that way. Declaring a variable in the catch block that you use in the finally block does work, with var (because var is not block-scoped and is hoisted), but it's misleading to people trying to maintain the code. If you're going to use a variable in both of those blocks, move the declaration outside the blocks for clarity.
Check this It will work
try{
console.log(myVar);
}
catch(err){
var myError = err;
var myErrorName = err.name;
var myErrorMessage = err.message;
}
finally{
if(myError){
var result = "There was an error ("+ myErrorName+": "+myErrorMessage+")";
}else{
result = "No error ocurred";
}
}
Are you doing typical CRUD UI code? Use try catches, use loops that go to 10000 for no reason sprinkled in your code, hell, use angular/ember - you will not notice any performance issue.
If you are doing low level library, physics simulations, games, server-side etc then the never throwing try-catch block wouldn't normally matter at all but the problem is that V8 didn't support it in their optimizing compiler until version 6 of the engine, so the entire containing function that syntactically contains a try catch will not be optimized. You can easily work around this though, by creating a helper function like tryCatch:
function tryCatch(fun) {
try {
return fun();
}
catch(e) {
tryCatch.errorObj.e = e;
return tryCatch.errorObj;
}
}
tryCatch.errorObj = {e: null};
var result = tryCatch(someFunctionThatCouldThrow);
if(result === tryCatch.errorObj) {
//The function threw
var e = result.e;
}
else {
//result is the returned value
}
After V8 version 6 (shipped with Node 8.3 and latest Chrome), the performance of code inside try-catch is the same as that of normal code.
The original question asked about the cost of try/catch when an error was not thrown. There is definitely an impact when protecting a block of code with try/catch, but the impact of try/catch will vanish quickly as the code being protected becomes even slightly complex.
Consider this test: http://jsperf.app/try-catch-performance-jls/2
A simple increment runs at 356,800,000 iterations per second The same increment within a try/catch is 93,500,000 iterations per second. That's on overhead of 75% due to try/catch. BUT, a trivial function call runs at 112,200,000 iterations per second. 2 trivial function calls run at 61,300,000 iterations per second.
An un-exercised try in this test takes slightly more time than one trivial function call. That's hardly a speed penalty that matters except in the inner-most loop of something really intense like an FFT.
The case you want to avoid is the case where an exception is actually thrown. That is immensely slower, as shown in the above link.
Edit: Those numbers are for Chrome on my machine. In Firefox there is no significant difference between an unexercised try and no protection at all. There's essentially zero penalty to using try/catch if no exception is thrown.