17. Optional catch binding
This chapter explains the ES2019 feature “Optional catch binding” by Michael Ficarra.
17.1. Overview
The proposal allows you to do the following:
That is useful whenever you don’t need the binding (“parameter”) of the catch
clause:
If you never use the variable error
, you may as well omit it, but JavaScript doesn’t let you do catch ()
. Furthermore, linters that check for unused variables complain in such cases.
17.2. Use cases
There are two general reasons for omitting the catch
binding:
- If you want to completely ignore the error.
You don’t care about the error or you already know what it will be, but you do want to react to it. My recommendation is to avoid doing that:
Instead of completely ignoring an error, at least log it to the console.
- Instead of assuming you know what the error will be, check for unexpected types of exceptions and re-throw them. If you can’t and don’t want to avoid it, I suggest encapsulating your code, e.g. inside a function, and to document it well.
Next, we’ll take a look at use cases for omitting catch
bindings and at risks and alternatives.
17.2.1. Use case: JSON.parse()
With JSON.parse()
, there is one predictable kind of exception – if the input is not legal JSON:
> JSON.parse('abc')
SyntaxError: Unexpected token a in JSON at position 0
That’s why it can make sense to use it like this:
There is one problem with this approach: errors in line A that are not related to parsing will be silently ignored. For example, you may make a typo such as JSON.prase(str)
. Cases like this have bitten me a few times in the past. Therefore, I now prefer to conditionally re-throw the errors I catch:
17.2.2. Use case: property chains
When accessing nested properties that may or may not exist, you can avoid checking for their existence if you simply access them and use a default if there is an exception:
I prefer explicit checks. For example:
This code can be shortened if you consider that the &&
operator returns the first falsy operand or the last operand (if there is no falsy operand):
However, this shorter version is also more obscure.
17.2.3. Use case: assert.throws()
Node.js has the API function assert.throws(func)
that checks whether an error is thrown inside func
. It could be implemented as follows.
This function is an example of wrapping an documenting code that ignores caught exceptions.
17.2.4. Use case: feature detection
The following code snippet demonstrates how to detect whether a given feature exists:
17.2.5. Use case: even logging fails
If even logging doesn’t work then, as a last resort, you have no choice but to ignore exceptions (because further logging could make things worse).
Again, we encapsulate and document the slightly unorthodox code.
17.3. Further reading
- Stack Exchange: “Is it ever ok to have an empty catch statement?”
- GitHub issue (repo of proposal): “Why?”