-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #334 * Add wrapping errors. Before there was one page about error handling. Now there are three. A simple page (the first part of the existing page). Then a new page about wrapping errors. And the third page is the second half of the existing page (custom errors). * ... addressed pr feedback. * ./tools/build was run.
- Loading branch information
Showing
15 changed files
with
596 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// It's possible to use custom types as `error`s by | ||
// implementing the `Error()` method on them. Here's a | ||
// variant on the example above that uses a custom type | ||
// to explicitly represent an argument error. | ||
|
||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
) | ||
|
||
// It's possible to use custom types as `error`s by | ||
// implementing the `Error()` method on them. Here's a | ||
// variant on the example above that uses a custom type | ||
// to explicitly represent an argument error. | ||
// A custom error type has usualy the suffix "Error". | ||
type argError struct { | ||
arg int | ||
message string | ||
} | ||
|
||
func (e *argError) Error() string { | ||
return fmt.Sprintf("%d - %s", e.arg, e.message) | ||
} | ||
|
||
func f(arg int) (int, error) { | ||
if arg == 42 { | ||
// In this case we use `&argError` syntax to build | ||
// a new struct, supplying values for the two | ||
// fields `arg` and `message`. | ||
return -1, &argError{arg, "can't work with it"} | ||
} | ||
return arg + 3, nil | ||
} | ||
|
||
func main() { | ||
// If you want to programmatically use the data in | ||
// a custom error, you'll need to get the error as an | ||
// instance of the custom error with errors.As() | ||
_, err := f(42) | ||
var ae *argError | ||
if errors.As(err, &ae) { | ||
fmt.Println(ae.arg) | ||
fmt.Println(ae.message) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
e7d16589797f94ba3ad1e75449b5f27c71d73a41 | ||
9pZvObLbmb8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
42 | ||
can't work with it |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
00affa44cc98f14c2b10934a4187c9445fac0fe6 | ||
NiJOpCPO3L0 | ||
bd2a75026d7959adf8e633c6084343740dfe842e | ||
o2xrWWk_1MU |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,6 @@ | ||
$ go run errors.go | ||
f1 worked: 10 | ||
f1 failed: can't work with 42 | ||
f2 worked: 10 | ||
f2 failed: 42 - can't work with it | ||
42 | ||
can't work with it | ||
f worked: 10 | ||
f failed: can't work with 42 | ||
# See this [great post](https://go.dev/blog/error-handling-and-go) | ||
# on the Go blog for more on error handling. |
71 changes: 71 additions & 0 deletions
71
examples/wrapping-and-sentinel-errors/wrapping-and-sentinel-errors.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Wrapping errors is a technique that allows you to add additional context | ||
// to an error while preserving the original error. | ||
// This approach is beneficial for debugging and understanding | ||
// the chain of events that led to an error, especially in | ||
// complex applications with multiple layers of function calls. | ||
|
||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"math/rand/v2" | ||
) | ||
|
||
// A sentinel error is a predeclared error variable that is used to | ||
// signify a specific error condition. It allows error values to be compared | ||
// directly via errors.Is() specific types of errors. | ||
var ErrOutOfTea = fmt.Errorf("no more tea available") | ||
|
||
var ErrPower = fmt.Errorf("can't boil water") | ||
|
||
func MakeTea() error { | ||
if rand.Int32N(4) == 0 { | ||
return ErrOutOfTea | ||
} | ||
if rand.Int32N(7) == 0 { | ||
// You can wrap an error with %w | ||
return fmt.Errorf("add custom text: %w", ErrPower) | ||
} | ||
return nil | ||
} | ||
|
||
func main() { | ||
err := makeTeaSeveralTimes() | ||
if err != nil { | ||
fmt.Println("One or serveral errors occured") | ||
} | ||
} | ||
|
||
func makeTeaSeveralTimes() error { | ||
var allErrs []error | ||
for range 14 { | ||
err := MakeTea() | ||
if err != nil { | ||
allErrs = append(allErrs, err) | ||
// errors.Is is a function in Go that checks if a given error | ||
// matches a specific error value. It's used to determine whether | ||
// an error (or any error in its chain) is equivalent to a particular | ||
// target error. This is especially useful with wrapped or nested errors, | ||
// allowing you to identify specific error types or sentinel errors in | ||
// a chain of errors. | ||
// By using several if-statements we can handle | ||
// different sentinel errors. | ||
// A switch statement is not applicable here. | ||
if errors.Is(err, ErrOutOfTea) { | ||
fmt.Println("We should buy new tea!") | ||
continue | ||
} | ||
if errors.Is(err, ErrPower) { | ||
fmt.Println("Now it is dark.") | ||
continue | ||
} | ||
fmt.Printf("Some unknown error: %s", err) | ||
continue | ||
} | ||
fmt.Println("The tea is warm and inviting.") | ||
} | ||
|
||
// Several errors can be joined to one error. | ||
return errors.Join(allErrs...) | ||
} |
2 changes: 2 additions & 0 deletions
2
examples/wrapping-and-sentinel-errors/wrapping-and-sentinel-errors.hash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
7e7e1b26a554f1737d79c8f64336548711eae60a | ||
9Ck6s3dPplR |
16 changes: 16 additions & 0 deletions
16
examples/wrapping-and-sentinel-errors/wrapping-and-sentinel-errors.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
$ go run wrapping-and-sentinel-errors.go | ||
The tea is warm and inviting. | ||
The tea is warm and inviting. | ||
The tea is warm and inviting. | ||
The tea is warm and inviting. | ||
We should buy new tea! | ||
The tea is warm and inviting. | ||
The tea is warm and inviting. | ||
The tea is warm and inviting. | ||
Now it is dark. | ||
The tea is warm and inviting. | ||
The tea is warm and inviting. | ||
The tea is warm and inviting. | ||
We should buy new tea! | ||
The tea is warm and inviting. | ||
One or serveral errors occured |
Oops, something went wrong.