try expressions
Proposal for simpler error handling
when using functions and Promises in ECMAScript
The current try...catch
error handling pattern leads to uncaught exceptions when dealing with promises. This is a new try
syntax to combine a Promise's value and error or wrap an expression in a try...catch
with a single return type.
let [json, jsonErr] = try JSON.parse('{}')
let [value, err] = try await fetch()
// instead of
let json, jsonErr, value, err
try {
json = JSON.parse('{}')
} catch (_jsonErr) {
jsonErr = _jsonErr
}
try {
value = await fetch()
} catch (_err) {
err = _err
}
It's backwards-compatible with existing
try...catch
usage, functions and expressions.
interface TryExpressionReturn {
[0]: any
[1]: Error
}
async function fetchUser(userId) {
let [gqlRes, gqlErr] = try await fetch(GRAPHQL_HOST + queryForUser(userId))
if (!gqlErr) return gqlRes
// If the GraphQL server doesn't respond properly, use fallback API
let [apiRes, apiErr] = try await fetch(`${V1_API_HOST}/v1/users/${userId}`)
// If the fallback API fails, throw the error
if (apiErr) throw apiErr
return apiRes
}
// Or for error reporting
let [, err] = try importantFn()
reprotError(err)
reportError((try importantFn())[1])
- Array return type. This removes unnecessary opinion and bytes from source compared to using an Object.
- 👍
let [myValue, myError] = try await fn()
- 👎
let { value: myValue, error: myError } = try await fn()
- 👍
- Array order inspired by Golang. This seems to make more sense instead of callback-style with error as the first argument, e.g.
res, err := http.Get(API_HOST)
async function fetchUser(userId) {
try {
return await fetch(GRAPHQL_HOST + queryForUser(userId))
} catch (gqlErr) {
try {
return await fetch(`${V1_API_HOST}/v1/users/${userId}`)
} catch (apiErr) {
throw apiErr
}
}
}
async function fetchUser(userId) {
let gqlErr, gqlErr
gqlRes = await fetch(GRAPHQL_HOST + queryForUser(userId)).catch(err => gqlErr = err)
if (gqlErr) {
return await fetch(`${V1_API_HOST}/v1/users/${userId}`)
}
return gqlRes
}
- This proposal is implemented as a Babel plugin to compile try expressions down to valid ECMAScript
- Backwards-compatible with existing exception handling and Promise spec
- Open to community for comment and testing