A try without a catch clause sends its error to the next higher catch, or the window, if there is no catch defined within that try.
If you do not have a catch, a try expression requires a finally clause.
try {
// whatever;
} finally {
// always runs
}
Answer from kennebec on Stack OverflowA try without a catch clause sends its error to the next higher catch, or the window, if there is no catch defined within that try.
If you do not have a catch, a try expression requires a finally clause.
try {
// whatever;
} finally {
// always runs
}
It's possible to have an empty catch block, without an error variable, starting with ES2019. This is called optional catch binding and was implemented in V8 v6.6, released in June 2018. The feature has been available since Node 10, Chrome 66, Firefox 58, Opera 53 and Safari 11.1.
The syntax is shown below:
try {
throw new Error("This won't show anything");
} catch { };
You still need a catch block, but it can be empty and you don't need to pass any variable. If you don't want a catch block at all, you can use the try/finally, but note that it won't swallow errors as an empty catch does.
try {
throw new Error("This WILL get logged");
} finally {
console.log("This syntax does not swallow errors");
}
I want to try action A, and if it fails try action B, and if it fails, try action C. I need to do that without having to specify a "catch". Is that possible? Thanks!
language agnostic - Why use try … finally without a catch clause? - Software Engineering Stack Exchange
Can I use a try/catch in JavaScript without specifying the catch argument/identifier? - Stack Overflow
Can I break a try - catch in JS without throwing exception?
try without catch/finally is not documented
Videos
It depends on whether you can deal with the exceptions that can be raised at this point or not.
If you can handle the exceptions locally you should, and it is better to handle the error as close to where it is raised as possible.
If you can't handle them locally then just having a try / finally block is perfectly reasonable - assuming there's some code you need to execute regardless of whether the method succeeded or not. For example (from Neil's comment), opening a stream and then passing that stream to an inner method to be loaded is an excellent example of when you'd need try { } finally { }, using the finally clause to ensure that the stream is closed regardless of the success or failure of the read.
However, you will still need an exception handler somewhere in your code - unless you want your application to crash completely of course. It depends on the architecture of your application exactly where that handler is.
The finally block is used for code that must always run, whether an error condition (exception) occurred or not.
The code in the finally block is run after the try block completes and, if a caught exception occurred, after the corresponding catch block completes. It is always run, even if an uncaught exception occurred in the try or catch block.
The finally block is typically used for closing files, network connections, etc. that were opened in the try block. The reason is that the file or network connection must be closed, whether the operation using that file or network connection succeeded or whether it failed.
Care should be taken in the finally block to ensure that it does not itself throw an exception. For example, be doubly sure to check all variables for null, etc.
Optional catch binding in 2019
Node.js
In Node.js, this feature is called Optional Catch Binding and is supported since Node.js version 10.3, see https://node.green.
Typescript
In Typescript, this is allowed since version 2.5.
Browser support
- Chrome: since 68
- Firefox: since 58
- Edge, IE, Safari: no support for now
Standard
The proposal is currently Stage 4, meaning that its implementation is finished and it is guaranteed to be included into the next version of the ECMAScript standard.
So this is a perfectly legitimate syntax now according to the standard if you are using Node.js or transpiling your browser code using Babel:
try {
} catch {
// No need for the `(error)` after `catch`!
}
This is an outdated answer. It no longer applies to the current version of JavaScript. See other answers for details.
You just can't. The spec says that there must always be an identifier inside parens after catch.
You can label a block and break from it using the break label syntax
as per your edit, finally is still executed
foo = function(){
var bar = Math.random() > .5;
omgalabel: try {
if( bar ) break omgalabel;
console.log( bar );
// code
}
catch( e ){
// This code should not execute if !!bar
}
finally {
// Code that executes no matter what
console.log( true );
}
}
foo = function(){
var bar = Math.random() > .5;
if( ! bar ) {
try{
// This code should not execute if !!bar
alert( bar );
}
catch( e ){
console.error(e);
}
}
// Code that executes no matter what
alert( true );
}
foo();
Why don't you check the boolean before you enter the try…catch?
I don't need the catch block.
But you do need to catch. The behavior of your code with a catch block is to catch any exception, and then forget that it happened. So any exception that tries to pass through will stop, and your code will basically pretend that the try block executed successfully.
So you want a naked try block to act like it catches an exception and ignores it. Here's the thing: a default case is meant to be a common case, one that is useful by many users and not error prone. if doesn't typically require an else because there are many cases where you have nothing to do.
I know nothing about why you want to drop exceptions on the floor and pretend they didn't happen. I'm willing to accept that you have some good justification for doing so. But the fact is, in the general case, it's not a good idea. Most programmers don't want to do it, and there are good arguments to say that it is generally unwise to do this sort of thing.
A good language will let you do something unwise. But a good language will not let you do something unwise by accident. Since the behavior you want is generally unwise, languages tend to make you explicitly request it.
As others have pointed out, there are good reasons why a plain try is not allowed in JavaScript, or in most other languages that have the same syntax:
It's not even obvious what it should do: for consistency with
try...finally, atrywith nocatchshould arguably just let any exceptions through without, well, catching them. But without acatchor afinallyblock, such a plaintrywould be useless.Most likely, a
trywithout acatch(or afinally) is just an editing mistake, just like anelsewithout anif. It's a good thing for the parser to notice and inform you of such mistakes.Catching exceptions and ignoring them completely is an unusual and risky thing to do, since it's easy to catch more than you expected. If you really want to do it, it's a good thing that the language at least forces you to be explicit about it.
In particular, note that your example code is kind of fragile and makes it easy to introduce subtle bugs that can be hard to detect and debug, since everything will seem to behave normally. For instance, let's make the following seemingly harmless change to your example:
// setting defaults ahead of try - no need for a catch block?
var setting = 10;
var myRegEx = optimizeRegEx("/123/g");
var supportsRegEx2 = false;
try {
const utils = require("applicationutils");
setting = 20;
myRegEx = optimizeRegEx("/123/gm");
supportsRegEx2 = true;
}
catch (e) {} // why does JS force me to do this?
Can you see what might go wrong here? I'll give you a moment to think about it...
OK, so what happens if optimizeRegEx() has a bug and crashes when given the input "/123/gm"? That exception will also be caught and ignored, since it happens inside the try block, so you'll never see it! Worse, now your variables will end up in an inconsistent state: setting will be 20 and the applicationutils module will be loaded, but myRegEx will still have its original value and supportsRegEx2 will be false. Have fun debugging that!
So how would you do that safely? Well, the first thing would be to ensure that the variables always end up in a consistent state, at least. One way to do that would be to (re)set them to their defaults in the catch block:
// these will be set inside the try/catch block below
var setting, myRegEx, supportsRegEx2;
try {
const utils = require("applicationutils");
setting = 20;
myRegEx = optimizeRegEx("/123/gm");
supportsRegEx2 = true;
}
catch (e) {
// something went wrong, probably require() failed: use fallback defaults instead
setting = 10;
myRegEx = optimizeRegEx("/123/g");
supportsRegEx2 = false;
}
That's a bit better: any exceptions from optimizeRegEx("/123/gm") will still be silently thrown away, but at least all the variables will end up with their default values if that happens.
Even better would be to fix the code to only catch the specific exception thrown when the require() fails. Unfortunately JavaScript makes this harder than it should be, since it doesn't support conditional catch clauses. But we can at least follow the general principle of having as little code as possible inside each try to avoid catching unexpected exceptions, and we can also inspect the caught exception inside the catch block and rethrow it if it's not what we expected to see:
// setting defaults ahead of try
var setting = 10;
var myRegEx = optimizeRegEx("/123/g");
var supportsRegEx2 = false;
// try loading utils, catch and ignore module loading error
var utils = null;
try {
utils = require("applicationutils");
}
catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') throw e; // rethrow any unexpected errors
}
// adjust variables if the module loaded without errors
if (utils !== null) {
setting = 20;
myRegEx = optimizeRegEx("/123/gm");
supportsRegEx2 = true;
}
(Error code test based on this answer on SO.)
Now we're only ignoring those errors that come from the statement that we expect to throw them and which also look like the error we expect. This minimizes the risk of us accidentally ignoring an error that wasn't the harmless one we were expecting, and thus makes the code more robust and easier to debug.
Regarding your actual use case (now that you've described it), it seems to me that what you really want is a wrapper function like this:
function tryRequire(moduleName) {
try {
return require(moduleName);
}
catch (e) {
if (e.code === 'MODULE_NOT_FOUND') return null; // adjust this as needed to detect module loading errors in your environment
throw e; // rethrow any unexpected errors
}
}
This way, you can just do const foo = tryRequire('foo'), and then check whether the module was successfully loaded based on whether foo is null.