|
| 1 | +Design for go-errors refactor |
| 2 | + |
| 3 | +# Introduction |
| 4 | +The main objective of this refactor is to ease the usage of go-errors library, with key points |
| 5 | +* One unique function with argument for standard error and go-errors |
| 6 | +* Variadic options following the "Functional Options" pattern |
| 7 | +* An error code, obtained by concatenating identifiers defined at each calls of subfunctions, that allow tracing the root cause |
| 8 | +* Comply with error interface (Error() string) |
| 9 | + |
| 10 | +# One unique function |
| 11 | +The signature of this unique function would be: |
| 12 | +```go |
| 13 | +func Wrap(error, errors.Opts...) error |
| 14 | +``` |
| 15 | +Where error can be of type |
| 16 | +1. standard errors |
| 17 | +2. go-errors |
| 18 | + |
| 19 | +## standard errors |
| 20 | +The provided error will be considered as a root error and stored as cause of a new go-errors one |
| 21 | + |
| 22 | +## go-errors |
| 23 | +The provided error will be considered as a template for a new go-errors one |
| 24 | + |
| 25 | +# Variadic Options |
| 26 | +The variadic options would be the following one |
| 27 | + |
| 28 | +* WithDetail: provide a message that details the error |
| 29 | +* WithProperty: provide a key/value pair for additional informations (filename, path, username, ... ) |
| 30 | +* WithIdentifier: used to provide an identifer, it could be concatenated with other idenfier from previous calls from subfunctions (See example below for clarity) |
| 31 | + |
| 32 | +Signature could be as follow |
| 33 | + |
| 34 | +```go |
| 35 | +errors.WithIdentifier(int): |
| 36 | +errors.WithDetail(string) |
| 37 | +errors.WithDetailf(string, ...any) |
| 38 | +errors.WithProperty(string, any) |
| 39 | +``` |
| 40 | + |
| 41 | +# Identifier |
| 42 | + |
| 43 | +In the following situation, the program would return |
| 44 | +``` |
| 45 | +forbidden (19-12-2): permission denied: missing required role: File='test.txt', User='john.doe', Role:'Reader', at=(func='main.appel3', file='main.go', line='270') |
| 46 | +``` |
| 47 | + |
| 48 | +```go |
| 49 | +package main |
| 50 | + |
| 51 | +import ( |
| 52 | + "fmt" |
| 53 | + |
| 54 | + errors "github.com/scality/go-errors" |
| 55 | +) |
| 56 | + |
| 57 | +var ErrForbidden = errors.New("forbidden") |
| 58 | + |
| 59 | +func main(){ |
| 60 | + err := appel1() |
| 61 | + fmt.Println(err) |
| 62 | +} |
| 63 | +func appel1() error { |
| 64 | + return errors.Wrap( |
| 65 | + appel2(), |
| 66 | + errors.WithIdentifier(19), |
| 67 | + ) |
| 68 | +} |
| 69 | + |
| 70 | +func appel2() error { |
| 71 | + return errors.Wrap( |
| 72 | + appel3(), |
| 73 | + errors.WithDetail("missing required role"), |
| 74 | + errors.WithProperty("Role", "Reader"), |
| 75 | + errors.WithProperty("User", "john.doe"), |
| 76 | + errors.WithIdentifier(12), |
| 77 | + ) |
| 78 | +} |
| 79 | + |
| 80 | +func appel3() error { |
| 81 | + // Something went wrong here |
| 82 | + return errors.Wrap( |
| 83 | + ErrForbidden, |
| 84 | + errors.WithIdentifer(2), |
| 85 | + errors.WithDetail("permission denied"), |
| 86 | + errors.WithProperty("File", "test.txt"), |
| 87 | + ) |
| 88 | +} |
| 89 | +``` |
0 commit comments