# catch Error

**URL:** <https://es.discourse.group/t/catch-error/904>\
**Category:** 💡 Ideas\
**Created:** [August 7, 2021, 4:10am UTC](https://es.discourse.group/t/catch-error/904 "2021-08-07T04:10:32Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mmkal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mmkal/32/2650_2.png) [@mmkal](https://es.discourse.group/u/mmkal)\
**Post date:** [August 7, 2021, 4:10am UTC](https://es.discourse.group/t/catch-error/904/1 "2021-08-07T04:10:32Z")

</div>

Catching errors without taking unsafe shortcuts is pretty awkward. Since anything can be thrown, we have to write type checks before dealing with `Error` instances. This is usually not well tested code since it's unusual for non-Errors to be thrown. Typescript users are extra aware of this problem, especially when using lint rules that prevent implicit/explicit `any`. What if we could do:

```javascript
try {
  foo();
} catch Error (e) {
  console.log(e.stack);
}

```

Where `Error` could be any identifier. The above would be syntactic sugar for

```javascript
try {
  foo();
} catch (_e) {
  let e = Error[Symbol.errorFromUnknown](_e);
  console.log(e.stack);
}

```

And `[Symbol.errorFromUnknown]` would be a new static property on `Error` looking something like:

```javascript
val => val instanceof Error ? val : new Error(`Non-error object: ${val}`)

```

Users would be free to define their own classes with similar properties that could wrap Errors in bespoke ways:

```javascript
class MyCompanyError extends Error {
  constructor(message, cause) {
    super(message)
    this.cause = cause
  }
  static [Symbol.errorFromUnknown](val) {
    if (val instanceof MyCompanyError) {
      return val
    }
    if (val instanceof Error) {
      return new MyCompanyError('foo', val)
    }
    return new MyCompanyError ('bar')
  }
}

```

In typescript, the type could be inferred from the return type of of the [Symbol.errorFromUnknown] function and no more awkward annotations or lint suppressions would be needed.

---

<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 7, 2021, 4:24am UTC](https://es.discourse.group/t/catch-error/904/2 "2021-08-07T04:24:41Z")

</div>

Interesting idea. This sounds like an issue that could potentially be solved in a more general purpose way. For example, I know it's common for a function that expects a string to take whatever parameter it recieves and coerce it into a string, as a first step, like this:

```javascript
function concat(x_, y_) {
  const x = String(x_)
  const y = String(y_)
  return x + y
}

```

What if, at _any_ location where you're binding a value to a variable, you're allowed to pass the incomming value through a normalization function first, through, say, a "from" keyword (I don't like this "from" word - feel free to bikeshed it). That would make the above example equivalent to this:

```javascript
function concat(x from String, y from String) {
  return x + y
}

```

It would also allow you to automatically coerce an unknown value to an error.

```javascript
try {
  foo();
} catch (e from Error) {
  console.log(e.stack);
}

// ... is the same as ...

try {
  foo();
} catch (e_) {
  let e = Error(e_)
  console.log(e.stack);
}

```

Some more usage examples :

```javascript
const normalizedDegrees = deg => deg % 360

function toRadians(deg from normalizedDegrees) {
  // ...
}

```

```javascript
const positiveNumberAssertion = value => {
  if (value <= 0) throw new Error('Whoops!')
  return value
}

function doOperation(x from positiveNumberAssertion) {
  // ...
}

```

```javascript
const {
  index from i => i + 1,
  ...otherParams
} = data

```

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [August 7, 2021, 6:24am UTC](https://es.discourse.group/t/catch-error/904/3 "2021-08-07T06:24:25Z")

</div>

> [@mmkal](#):
>
> And `[Symbol.errorFromUnknown]` would be a new static property on `Error` looking something like:
> 
> ```javascript
> val => val instanceof Error ? val : new Error(`Non-error object: ${val}`)
> 
> ```

Be aware that `instanceOf` checks do not work across Realms, e.g an error that comes from a different iFrame.

---

<div class="post-metadata">

**Author:** ![mmkal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mmkal/32/2650_2.png) [@mmkal](https://es.discourse.group/u/mmkal)\
**Post date:** [August 7, 2021, 4:04pm UTC](https://es.discourse.group/t/catch-error/904/4 "2021-08-07T16:04:14Z")

</div>

> Be aware that instanceOf checks do not work across Realms, e.g an error that comes from a different iFrame.

@aclaymore interesting, I'm mostly writing server-side js so haven't come across this. Although the actual implementation of the `Error`-coercer is just a strawman. It could check that the shape is error-like instead of using `instanceof`.

---

<div class="post-metadata">

**Author:** ![mmkal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mmkal/32/2650_2.png) [@mmkal](https://es.discourse.group/u/mmkal)\
**Post date:** [August 7, 2021, 4:10pm UTC](https://es.discourse.group/t/catch-error/904/5 "2021-08-07T16:10:43Z")

</div>

@theScottyJam I love that idea. That could effectively give opt-in type checking to plain javascript. I feel like you could go really, really far with it. If it were implemented, eventually type annotations might not be needed in application code by using a runtime type checking library:

```javascript
import { z } from 'zod'

const User = z.object({
  name: z.string(),
  email: z.string().email(),
})

const greetUser = (user from User.parse) => {
  console.log(`Hello ${user.name}, your email is ${user.email}`)
}

```

---

<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 7, 2021, 4:19pm UTC](https://es.discourse.group/t/catch-error/904/6 "2021-08-07T16:19:31Z")

</div>

In node, this can also happen from using the vm module.

---

<div class="post-metadata">

**Author:** ![mmkal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mmkal/32/2650_2.png) [@mmkal](https://es.discourse.group/u/mmkal)\
**Post date:** [August 7, 2021, 5:14pm UTC](https://es.discourse.group/t/catch-error/904/7 "2021-08-07T17:14:53Z")

</div>

Got it. I prefer the broader parameter coercion idea anyway, so I think I'll edit the original post. That way the specific error coercion function is removed from scope. The [error cause proposal](https://github.com/tc39/proposal-error-cause) could be a good way of making a wrapper that coerces to an Error safely. The original error from another realm could become the `cause`. But again, with @theScottyJam 's idea this proposal wouldn't really need to worry about that (it could just motivate an "official" Error coercer function in a separate mini-proposal).

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [August 8, 2021, 4:29pm UTC](https://es.discourse.group/t/catch-error/904/8 "2021-08-08T16:29:26Z")

</div>

Is there a risk that someone could interpret this as something that _only_ catches `Error`? Similar to how catch works in languages like c++ and Java when the type is on the other side of the open bracket.

---

<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 8, 2021, 4:56pm UTC](https://es.discourse.group/t/catch-error/904/9 "2021-08-08T16:56:02Z")

</div>

That's honestly how I would have interpreted the initial idea for this proposal, if I saw that syntax without context.

---

<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 8, 2021, 5:17pm UTC](https://es.discourse.group/t/catch-error/904/10 "2021-08-08T17:17:32Z")

</div>

Catch guards are a useful proposal, and that’s what this looks like. Coercing to an error doesn’t seem valuable to me.

---

<div class="post-metadata">

**Author:** ![mmkal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mmkal/32/2650_2.png) [@mmkal](https://es.discourse.group/u/mmkal)\
**Post date:** [August 8, 2021, 6:10pm UTC](https://es.discourse.group/t/catch-error/904/11 "2021-08-08T18:10:10Z")

</div>

If we change it to @theScottyJam's idea, maybe we'd also get catch guards almost for free:

```javascript
const rethrowIfNot = type => err => {
  if (err instanceof type) {
    return err
  }
  throw err
}

try {
  foo();
} catch (err from rethrowIfNot(TypeError)) {
  console.log('type error!')
}

```

Although it wouldn't allow for multiple catches.

---

<div class="post-metadata">

**Author:** ![mmkal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/mmkal/32/2650_2.png) [@mmkal](https://es.discourse.group/u/mmkal)\
**Post date:** [August 12, 2021, 2:23pm UTC](https://es.discourse.group/t/catch-error/904/12 "2021-08-12T14:23:26Z")

</div>

I created a new topic; I officially disown this one: [Parameter coercion](https://es.discourse.group/t/parameter-coercion/920)
