# Universal and conditional catch blocks with the new when keyword

**URL:** <https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122>\
**Category:** 🦋 Proposals\
**Tags:** proposal\
**Created:** [August 28, 2024, 4:14am UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122 "2024-08-28T04:14:49Z")\
**Posts on this page:** 11\
**Page:** 1

<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:** [August 28, 2024, 4:14am UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/1 "2024-08-28T04:14:49Z")

</div>

#### Proposal: [GitHub - rafageist/proposal-universal-catch-and-when: Proposal to extend error handling in ECMAScript by allowing any block to have multiple "catch" and "finally" clauses. A new "when" clause is introduced for conditional errors and the "catch" body is allowed to be optional.](https://github.com/rafageist/proposal-universal-catch-and-when)

This proposal expands JavaScript's current `try-catch` mechanism by allowing any code block to have an optional `catch` and `finally` block. The `catch` block can also be enhanced with a `when` clause, enabling conditional error handling directly within the block. This approach maintains consistency with JavaScript's existing syntax and structure, offering a natural extension of control flow mechanisms without introducing new, complex constructs.

```txt
/* 
any block of code: try, anonymous, functions, 
if, do, class, catch, finally, switch, ... 
*/ 

{
    // Code that may throw an error
    // ...
} 
catch (<var>) when (<boolean expression) 
{
    // Error-handling logic
    // ...
    // catch is also a block!
}
catch (<var>) when (<boolean expression>) 
{
    // Error-handling logic
    // ...
}
finally 
{
    // Cleanup code, executed regardless of success or failure

    // ... but finally is also a block!
} 
catch (<var>) when (<boolean expression>) 
{
    // Error-handling logic
    // ...
}
...

```

## Examples

### Anonymous block

```js
{
  doSomething();
} 
catch(err) when (err instanceof Error)
{
  console.log("Error: ", err);
}
catch(err) when (err instanceof TypeError)
{
  console.log("TypeError: ", err);
}
finally
{
  console.log("Finally block");
}

```

### Function block

```js
async function loadData() 
{
	return await fetch("https://api.example.com");
}
catch (err)
{
   	console.log("Error fetch data");
}

```

### If and else block

```js
if (condition == false)
{
	console.log("Condition is false");
} 
catch(err) when (err instanceof Error)
{
	console.log("Error condition");
}
else
{
	console.log("Condition is true");
}
catch(err) when (err instanceof TypeError)
{
	console.log("Error in else block");
}
finally
{
	console.log("Finally block after if-else");
}

```

### For loop block

```js
for (let i = 0; i < 10; i++)
{
	console.log(i);
}
catch (err)
{
	console.log("Error in loop");
}

```

### Switch block

```js
switch (condition)
{
	case 1:
		console.log("Case 1");
		break;
	case 2:
		console.log("Case 2");
		break;
	default:
		console.log("Default case");
}
catch (err)
{
	console.log("Error in switch");
}

```

### Class block

```js
class MyClass
{
	constructor()
	{
		console.log("MyClass constructor");
	}
}
catch (err)
{
	console.log("Error in class");
}

```

**... and more!**

This proposal is currently in need of a champion to help refine and present it to the TC39 committee. If you're interested in advocating for more flexible and structured error handling in JavaScript, your support would be invaluable. For more details, please read the proposal in the repository.

---

<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 28, 2024, 8:28am UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/2 "2024-08-28T08:28:28Z")

</div>

Related threads:

> [@Catch instanceof guards](https://es.discourse.group/t/catch-instanceof-guards/1160):
>
> It would be really nice to be able to write try { // some code } catch (error instanceof MyCustomError) { // handle the error } catch (error instanceof AnotherCustomError) { // handle the other error } instead of the more verbose try { // some code } catch (error) { if (error instanceof MyCustomError) { // handle the error } else if (error instanceof AnotherCustomError) { // handle the other error } else { throw error; } }

> [@\[Need Champion\] Catch guards](https://es.discourse.group/t/need-champion-catch-guards/1698):
>
> Proposal: [GitHub - jeengbe/proposal-catch-guards](https://github.com/jeengbe/proposal-catch-guards) The document proposes a new syntax for catch clauses with guards for better code readability: try { someFunction(); } catch ErrorA (err) { // Do something } catch ErrorB | ErrorC (err) { // Do another thing } catch { // Do a third thing } finally { // Clean up } The proposal is in need of a champion and a polished changeset to the spec.

---

<div class="post-metadata">

**Author:** ![bakkot](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bakkot/32/22_2.png) [@bakkot](https://es.discourse.group/u/bakkot)\
**Post date:** [August 28, 2024, 9:32pm UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/3 "2024-08-28T21:32:00Z")

</div>

Please do not use ChatGPT to write posts on this or any other forum.

---

<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:** [August 28, 2024, 11:34pm UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/4 "2024-08-28T23:34:22Z")

</div>

Ok. I haven't done it and I won't do it, because it's not necessary. Thanks for letting me know.

Do you have any questions about the proposal? Any suggestions?

---

<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 14, 2024, 6:33pm UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/5 "2024-09-14T18:33:05Z")

</div>

I have made a major update to my proposal. Now the body of the `catch` can also be optional. The variable that catches the error can be treated in the scope of the `catch`

```js
{ var result = await process() } catch (err);

console.log(result);

if (err) console.log(err);

```

This will allow for more flexibility in error catching, among other improvements to code readability.

```js
{ await process() } catch;

```

---

<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 15, 2024, 3:19am UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/6 "2024-09-15T03:19:26Z")

</div>

Another update: I have removed the Class catch, Object literal catch and Switch catch examples, as they do not have a Block definition. This remains to be analyzed.

---

<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 15, 2024, 12:15pm UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/7 "2024-09-15T12:15:51Z")

</div>

Update:

The concept of differentiating statement blocks and declarative blocks has been refined. A new issue has been opened for further analysis.

---

<div class="post-metadata">

**Author:** ![ReinsBrain](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/reinsbrain/32/1165_2.png) [@ReinsBrain](https://es.discourse.group/u/ReinsBrain)\
**Post date:** [October 17, 2024, 1:50am UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/8 "2024-10-17T01:50:43Z")

</div>

elegant solution - i love it. @rafageist , is a `constructor(){} catch{}` also supported?

---

<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:** [October 18, 2024, 7:52am UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/9 "2024-10-18T07:52:46Z")

</div>

> [@rafageist](#):
>
> Now the body of the `catch` can also be optional.

That would make currently valid code ambiguous.

```js
try { ... } catch
(e) // is this capturing `e`, or an expression statement after catch without capture&block?
{ ... } // is this error handling, or block statement after catch(e) without block?

```

> [@rafageist](#):
>
> The variable that catches the error can be treated in the scope of the `catch`

Changes meaning of currently valid code.

```javascript
try { ... }
catch (e)
{ ... }
console.log(e) // e from outer scope

```

---

<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:** [November 18, 2024, 10:49pm UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/10 "2024-11-18T22:49:25Z")

</div>

Thanks ReinsBrain

Yes, a catch{} block can be used inside a constructor because the constructor's body is an imperative block (like a function).

```javascript
class MyClass {
  constructor() {
    {
      throw new Error("Something went wrong");
    } catch (err) {
      console.log("Error handled in constructor:", err.message);
    }
  }
}

```

---

<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:** [November 18, 2024, 11:24pm UTC](https://es.discourse.group/t/universal-and-conditional-catch-blocks-with-the-new-when-keyword/2122/11 "2024-11-18T23:24:57Z")

</div>

Thank you, lightmare! This has already been addressed in the proposal (section: Importance of semi-colons). If the catch body is omitted, the syntax must explicitly use `catch;`, avoiding ambiguity. For example:

```javascript
try {
  throw new Error("Error in block");
} catch; // Explicitly ends the catch
(1 + 1);

```

Additionally, semicolons are recommended to clearly separate statements, ensuring there’s no confusion for the interpreter or developers.
