Suggestion
π Search Terms
Multiple catch, catch instanceof, typed catch
β
Viability Checklist
My suggestion meets these guidelines:
π Motivating Example
try {
JSON.parse(fs.readFileSync('save.json'));
} catch SyntaxError (err) {
// Corrupt save file; do nothing
}
// all other (fs) errors are nothing we want to deal here with and just pass right though
Previously, this would have required a much more nested and verbose body, such as:
try {
JSON.parse(fs.readFileSync('save.json'));
} catch (err) {
if (err instanceof SyntaxError) {
// Corrupt save file; do nothing
} else {
throw err;
}
}
β Suggestion
This suggestion extends the syntax of the catch statement by allowing one or more identifiers to restrict the type of errors that would be caught:
try {
someFunction();
} catch ErrorA (_err) {
console.log('Got error A')
} catch ErrorB | ErrorC (error) {
console.log('Got error B or C', error.message)
} catch (_err) {
console.log('Not sure what happened')
}
This would roughly translate to:
try {
someFunction();
} catch (_e1) {
// ^ free emit helper variable
if (_e1 instanceof ErrorA) {
let _err = _e1;
console.log('Got error A')
} else if (_e1 instanceof ErrorB || _e1 instanceof ErrorC) {
let error = _e1;
console.log('Got error B or C', error.message)
} else {
console.log('Not sure what happened')
}
}
To allow for multi-catch blocks, identifiers grouped with a | b | c translate to ||'ed instanceof expressions.
If no catch block without annotation is provided, the error is re-thrown:
try {
JSON.parse(fs.readFileSync('save.json'));
} catch SyntaxError (err) {
// Corrupt save file; do nothing
}
turns into
try {
JSON.parse(fs.readFileSync('save.json'));
} catch (_e1) {
if(_e1 instanceof SyntaxError) {
// Corrupt save file; do nothing
} else {
throw _e1;
}
}
No catch blocks may come after the "untyped" catch block, or else an unrecoverable syntax error is raised.
The types of the identifiers provided must satisfy the conditions for being used on the right-hand side of an instanceof expression and not be any or unknown.
If one of the provided annotations is of type any or unknown, a semantic error is raised.
For annotated catch blocks:
If not provided, the type of the variable of the catch statement is inferred to the type of the identifier used to restrict the clause.
If provided, it must be a supertype of that type or a semantic error is raised.
Type inference of the unannotated catch block (i.e. catch (err: unknown)) is not altered, hereby making the proposal fully backwards-compatible.
π» Use Cases
The goal of this proposal aligns with other languages' goals that also support multiple catch blocks:
Better code readability:
- Different errors are "separated and decoupled more"
- Familiar structure (other languages support multiple catch blocks)
- One less level of indentation
- Less if-instanceof-else boilerplate code
I would be willing to work on a PR.
Suggestion
π Search Terms
Multiple catch, catch instanceof, typed catch
β Viability Checklist
My suggestion meets these guidelines:
π Motivating Example
Previously, this would have required a much more nested and verbose body, such as:
β Suggestion
This suggestion extends the syntax of the catch statement by allowing one or more identifiers to restrict the type of errors that would be caught:
This would roughly translate to:
To allow for multi-catch blocks, identifiers grouped with
a | b | ctranslate to||'edinstanceofexpressions.If no catch block without annotation is provided, the error is re-thrown:
turns into
No catch blocks may come after the "untyped" catch block, or else an unrecoverable syntax error is raised.
The types of the identifiers provided must satisfy the conditions for being used on the right-hand side of an instanceof expression and not be
anyorunknown.If one of the provided annotations is of type
anyorunknown, a semantic error is raised.For annotated catch blocks:
If not provided, the type of the variable of the catch statement is inferred to the type of the identifier used to restrict the clause.
If provided, it must be a supertype of that type or a semantic error is raised.
Type inference of the unannotated catch block (i.e.
catch (err: unknown)) is not altered, hereby making the proposal fully backwards-compatible.π» Use Cases
The goal of this proposal aligns with other languages' goals that also support multiple catch blocks:
Better code readability:
I would be willing to work on a PR.