Skip to content

Commit 0c5125a

Browse files
refactor: Add Design.md to explain refactor
Signed-off-by: Anthony TREUILLIER <anthony.treuillier@scality.com>
1 parent 403a302 commit 0c5125a

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

DESIGN.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Introduction
2+
This library aims to simplify error handling in Go through the following key features
3+
* One unique function with argument for standard error and go-errors
4+
* Variadic options following the "Functional Options" pattern
5+
* An error code, obtained by concatenating identifiers defined at each calls of subfunctions, that allow tracing the root cause
6+
* Comply with error interface (Error() string)
7+
8+
# One unique function
9+
The signature of this unique function would be:
10+
```go
11+
func Wrap(error, errors.Opts...) error
12+
```
13+
Where error can be of type
14+
1. standard errors
15+
2. go-errors
16+
17+
## standard errors
18+
The provided error will be considered as a root error and stored as cause of a new go-errors one
19+
20+
## go-errors
21+
The provided error will be considered as a template for a new go-errors one
22+
23+
# Variadic Options
24+
The variadic options would be the following one
25+
26+
* `WithDetail`/`WithDetailf`: provide a message that details the error
27+
* `WithProperty`: provide a key/value pair for additional informations (filename, path, username, ... )
28+
* `WithIdentifier`: used to provide an identifer, it could be concatenated with other idenfier from previous calls from subfunctions (See example below for clarity)
29+
* `CausedBy`: used to trace a root error
30+
31+
Signature could be as follow
32+
33+
```go
34+
errors.WithDetail(string)
35+
errors.WithDetailf(string, ...any)
36+
errors.WithProperty(string, any)
37+
errors.WithIdentifier(int)
38+
errors.CausedBy(err error)
39+
```
40+
41+
# Identifier
42+
43+
Below an example of using `go-errors` with identifier.
44+
Also, find the expected error message
45+
46+
```go
47+
package main
48+
49+
import (
50+
"fmt"
51+
"os"
52+
53+
errors "github.com/scality/go-errors"
54+
)
55+
56+
var ErrForbidden = errors.New("forbidden")
57+
58+
func main(){
59+
err := call1()
60+
fmt.Println(err)
61+
}
62+
63+
func call1() error {
64+
return errors.Wrap(
65+
call2(),
66+
errors.WithIdentifier(19),
67+
)
68+
}
69+
70+
func call2() error {
71+
return errors.Wrap(
72+
call3(),
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 call3() error {
81+
// ls -l test.txt:
82+
// -rw------- 1 root root 5 Mar 5 08:18 test.txt
83+
_, err := os.Open("test.txt")
84+
85+
// Something went wrong here
86+
return errors.Wrap(
87+
ErrForbidden,
88+
errors.WithIdentifer(2),
89+
errors.WithDetail("permission denied"),
90+
errors.WithProperty("File", "test.txt"),
91+
errors.CausedBy(err),
92+
)
93+
}
94+
```
95+
96+
In the following situation, the program would return
97+
```
98+
forbidden (19-12-2): permission denied: missing required role: Role='Reader', User='john.doe', File='test.txt', at=(func='main.call3', file='main.go', line='41'), caused by: open test.txt: permission denied
99+
```

0 commit comments

Comments
 (0)