# Specific Exception Handling

**URL:** <https://es.discourse.group/t/specific-exception-handling/925>\
**Category:** 💡 Ideas\
**Created:** [August 13, 2021, 1:20pm UTC](https://es.discourse.group/t/specific-exception-handling/925 "2021-08-13T13:20:03Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![ethanlal04](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ethanlal04/32/918_2.png) [@ethanlal04](https://es.discourse.group/u/ethanlal04)\
**Post date:** [August 13, 2021, 1:20pm UTC](https://es.discourse.group/t/specific-exception-handling/925/1 "2021-08-13T13:20:03Z")

</div>

Hi,

Python has a syntax that lets us catch a specific kind of error. I'm surprised why this feature doesn't exist in Javascript.

This is the syntax I propose...

```javascript
try {
  // ...
} catch (ex instanceof TypeError) {
  // ...
}

```

We can use multiple catch blocks to catch different errors...

```javascript
try {
  // ...
} catch (ex instanceof TypeError) {
  // ...
} catch (ex instanceof EvalError) {
  // ...
}

```

We can use this when we need to do the same thing for different errors...

```javascript
try {
  // ...
} catch (ex instanceof TypeError | EvalError) {
  // ...
}

```

The last block in the below tree will be executed if the exception is not a `TypeError`...

```javascript
try {
  // ...
} catch (ex instanceof TypeError) {
  // ...
} catch (ex) {
  // ...
}

```

Thanks!

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [August 13, 2021, 1:50pm UTC](https://es.discourse.group/t/specific-exception-handling/925/2 "2021-08-13T13:50:36Z")

</div>

One problem is that some platforms/libraries use special properties on the error object instead of subclasses to make different error types (like node), so you would also need to provide a way to support them too. I had previously proposed providing [a standard exception class](https://es.discourse.group/t/a-standard-exception-class/790) to Javascript, which if used would make this kind of feature more palatable. The consensus in that proposal is that the design I came us with would probably break backwards compatibility, but it could still be possible to get everyone to use a standard system through a protocol, i.e. if an exception provided a unique key to a Symbol.exceptionType property (or just a non-symbol "code" property), and the catch clause would could check against a key. For example:

```javascript
DOMException[Symbol.exceptionType] = 'DOM:DOMException'
try {
  doSomeDomOperation()
} catch 'DOM:DOMException' (ex) { 
  console.log('A DOM exception was thrown!')
}

```

If we don't get everyone onto a standard, then your catch handler would need to be flexible enough to handle exception subtypes and unique properties on the error object. Here's one possibility:

```javascript
const isSubType = type => ex => ex instanceof type
const hasProperty = (key, value) => ex => ex[key] === value

try {
  ...
} catch where isSubType(DOMException) {
  ...
} catch where hasProperty('code', 'FileNotFound') {
  ...
}

```

---

<div class="post-metadata">

**Author:** ![ethanlal04](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ethanlal04/32/918_2.png) [@ethanlal04](https://es.discourse.group/u/ethanlal04)\
**Post date:** [August 13, 2021, 2:05pm UTC](https://es.discourse.group/t/specific-exception-handling/925/3 "2021-08-13T14:05:52Z")

</div>

Not sure if I follow you. I meant this...

```javascript
try {
  // ...
} catch (ex instanceof TypeError) {
  // ... 2
}

```

to be syntactic sugar over...

```javascript
try {
  // ...
} catch (ex) {
  if (ex instanceof TypeError) {
    // ... 2
  } else throw ex;
}

```

Thanks!

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 13, 2021, 2:21pm UTC](https://es.discourse.group/t/specific-exception-handling/925/4 "2021-08-13T14:21:35Z")

</div>

You don't need to limit yourself to `instanceof`. You could make `catch` accept any expression (where the exception would be bound to a fixed identifier, e.g. `error` or `exc`). The current form with a single name would be unaffected.

Or, you could replace `catch` with `match`:

```javascript
try {
  ...
} match (ex) { // binds just like `catch (ex)`
  // but here you do pattern matching
}

```

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [August 13, 2021, 2:23pm UTC](https://es.discourse.group/t/specific-exception-handling/925/5 "2021-08-13T14:23:48Z")

</div>

Yes, but take node for example. They don't subclass their fs errors, instead, they throw a regular error object and add a "code" property to them that explains what went wrong. For example, here's how you would handle a file-not-found error in node:

```javascript
try {
  fs.readFileSync(...)
} catch (ex) {
  if (ex.code === 'ENOENT') {
    ...
  } else throw ex
}

```

Javascript has never officially declared that "subclassing exceptions is the way to go", so many people do it in different ways, and we need to be conscientious about the different solutions out there when we make a catch handler. Our options are to either to make this syntax support all options, or provide a non-backwards-compatible-breaking path for library implementers to use, that would unify the different types of exceptions (such as, asking people to provide a unique value for their exception in a symbol).

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [August 13, 2021, 2:26pm UTC](https://es.discourse.group/t/specific-exception-handling/925/6 "2021-08-13T14:26:27Z")

</div>

@lightmare - the pattern-matching-catch thing is a good idea too. For reference, the pattern matching proposal actually shares almost exactly that as a potential solution to this problem, that could maybe be done in a follow-on proposal. See [here](https://github.com/tc39/proposal-pattern-matching#catch-guards).

And here's their code example:

```javascript
try {
  throw new TypeError('a');
} catch match (e) {
  if (e instanceof RangeError) { … }
  when (/^abc$/) { … }
  else { throw e; } // default behavior
}

```

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 13, 2021, 2:27pm UTC](https://es.discourse.group/t/specific-exception-handling/925/7 "2021-08-13T14:27:59Z")

</div>

Hehe, I skimmed the readme looking exactly for that, and couldn't find it :D

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [August 13, 2021, 3:22pm UTC](https://es.discourse.group/t/specific-exception-handling/925/8 "2021-08-13T15:22:29Z")

</div>

instanceof doesn’t work for cross-realm builtins, so I’d be staunchly opposed to anything that encourages its semantics.

Catch guards are a proposal i will likely be championing after pattern matching advances closer to stage 4.

---

<div class="post-metadata">

**Author:** ![rdking](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rdking/32/54_2.png) [@rdking](https://es.discourse.group/u/rdking)\
**Post date:** [August 14, 2021, 5:43pm UTC](https://es.discourse.group/t/specific-exception-handling/925/9 "2021-08-14T17:43:49Z")

</div>

What if `catch` accepted a function that returned a truthy value?

```javascript
try {
   let e = new Error;
   e.code = "SEGFAULT";
   throw e;
} catch (ex => e.code == "SEGFAULT") {
   try {
      throw new TypeError(e.code);
   } catch (ex2 => ex2 instanceof TypeError) {
      console.log("Caught them all!");
   }
}

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [August 14, 2021, 8:19pm UTC](https://es.discourse.group/t/specific-exception-handling/925/10 "2021-08-14T20:19:28Z")

</div>

what happens when that function throws an exception?

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [August 14, 2021, 9:34pm UTC](https://es.discourse.group/t/specific-exception-handling/925/11 "2021-08-14T21:34:46Z")

</div>

The problem I see with `catch (someFunction)` is that now you don't have a place to bind the thrown error to a variable, so such a function would need to be placed elsewhere, e.g. `catch when someFunction (err)`

If an error gets thrown inside the predicate, I'm not too concerned about what gets thrown from it, as long as something useful does. Such an error would only be caught or reported for debugging purposes, it's not something that should be recovered from. So, it could be that we bail the try-catch and let the error from the predicate be what get's propagated (similar to what happens when an error is thrown in a finally block). Or, we could throw an aggregate error containing both the original error and the error from the predicate. Either way works.

---

<div class="post-metadata">

**Author:** ![sirisian](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/sirisian/32/787_2.png) [@sirisian](https://es.discourse.group/u/sirisian)\
**Post date:** [August 15, 2021, 9:39pm UTC](https://es.discourse.group/t/specific-exception-handling/925/12 "2021-08-15T21:39:07Z")

</div>

In my [types notes](https://github.com/sirisian/ecmascript-types#exception-filters) there's a more compact syntax that I saw someone else suggest years ago:

```javascript
catch (e:TypeError|EvalError => e.message == 'a') { console.log(e); }

```

That said ljharb's comment is why I haven't moved it outside the future consideration notes. Being able to throw in the "when" part complicates things. Can return false or throw outside of the try. I don't even know what C# does in these cases.

---

<div class="post-metadata">

**Author:** ![rdking](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rdking/32/54_2.png) [@rdking](https://es.discourse.group/u/rdking)\
**Post date:** [August 16, 2021, 12:35am UTC](https://es.discourse.group/t/specific-exception-handling/925/13 "2021-08-16T00:35:18Z")

</div>

> [@ljharb](#):
>
> what happens when that function throws an exception?

It should be the same thing that happens when a normal catch throws. Remember that this is just candy for having exception type checking in the catch body.

> [@theScottyJam](#):
>
> The problem I see with `catch (someFunction)` is that now you don't have a place to bind the thrown error to a variable, so such a function would need to be placed elsewhere, e.g. `catch when someFunction (err)`

For this, there would be a few syntax restrictions, namely that the function must be an arrow function with no parenthesis for the single required parameter and a single non-block expression for the function body. The parameter variable would be passed on to the catch body.

---

<div class="post-metadata">

**Author:** ![rafageist](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rafageist/32/2200_2.png) [@rafageist](https://es.discourse.group/u/rafageist)\
**Post date:** [September 6, 2024, 1:47pm UTC](https://es.discourse.group/t/specific-exception-handling/925/14 "2024-09-06T13:47:30Z")

</div>

Related threads:

[Universal and conditional catch blocks with the new when keyword](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122)
