Description
Proposal Details
Proposal
Reduce boilerplate of handling errors by introducing a new catch statement, which works similar to switch
and select
, given the implicit error
value is non-nil.
// return bare error
f, err := os.Open(src) catch err
// return annotated error
f, err := os.Open(src) catch fmt.Errorf("open file: %w", err)
// switch on error type using a boolean expression
f, err := os.Open(src) catch {
case os.IsNotExist(err): errors.New("file not found")
case os.Permission(err): errors.New("permission denied")
default: fmt.Errorf("open file: %w", err)
}
Multiple return values
Given a function has multiple return values, the catch statement would look like this:
// return bare error
f, err := os.Open(src) catch nil, err
// return annotated error
f, err := os.Open(src) catch nil, fmt.Errorf("open file: %w", err)
// switch on error type using a boolean expression
f, err := os.Open(src) catch {
case os.IsNotExist(err): nil, errors.New("file not found")
case os.Permission(err): nil, errors.New("permission denied")
default: nil, fmt.Errorf("open file: %w", err)
}
The default
case
The default
case is effectively syntatic sugar for:
case err != nil: ...
No default
provided in catch block
Omitting the default
case in the catch block, should result in a compilation error for being non-exhaustive.
Rationale
Adding a new symbol like ?
or !
, although inspired by other languages, feels out of place in Go code, which is why I believe adding a new keyword instead is a more reasonable approach.
Many of the proposals from this meta issue only handle the err != nil
case, leaving it up to the developer to find a solution when trying to assert on the type of the error.
The new catch
statement feels more Go-like by borrowing well-established syntax from switch
and select
using the case
keyword to assert on the error type using a boolean expression.
Possible considerations for go fmt
Consider to align error handlers of case statements similar to how map key-value pairs are formatted:
f, err := os.Open(src) catch {
case os.IsNotExist(err): errors.New("file not found")
case os.Permission(err): errors.New("permission denied")
default: fmt.Errorf("open file: %w", err)
}
Activity
seankhliao commentedon Jan 31, 2025
Please fill out https://github.com/golang/proposal/blob/master/go2-language-changes.md when proposing language changes
seankhliao commentedon Jan 31, 2025
I believe this is sufficiently similar to #67955