diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..b72611c --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,92 @@ +Design for go-errors refactor + +# Introduction +The main objective of this refactor is to ease the usage of go-errors library, with key points +* One unique function with argument for standard error and go-errors +* Variadic options following the "Functional Options" pattern +* An error code, obtained by concatenating identifiers defined at each calls of subfunctions, that allow tracing the root cause +* Comply with error interface (Error() string) + +# One unique function +The signature of this unique function would be: +```go +func Wrap(error, errors.Opts...) error +``` +Where error can be of type +1. standard errors +2. go-errors + +## standard errors +The provided error will be considered as a root error and stored as cause of a new go-errors one + +## go-errors +The provided error will be considered as a template for a new go-errors one + +# Variadic Options +The variadic options would be the following one + +* `WithDetail`/`WithDetailf`: provide a message that details the error +* `WithProperty`: provide a key/value pair for additional informations (filename, path, username, ... ) +* `WithIdentifier`: used to provide an identifer, it could be concatenated with other idenfier from previous calls from subfunctions (See example below for clarity) + +Signature could be as follow + +```go +errors.WithDetail(string) +errors.WithDetailf(string, ...any) +errors.WithProperty(string, any) +errors.WithIdentifier(int) +``` + +# Identifier + +Below an example of using `go-errors` with identifier. +Also, find the expected error message + +```go +package main + +import ( + "fmt" + + errors "github.com/scality/go-errors" +) + +var ErrForbidden = errors.New("forbidden") + +func main(){ + err := appel1() + fmt.Println(err) +} +func appel1() error { + return errors.Wrap( + appel2(), + errors.WithIdentifier(19), + ) +} + +func appel2() error { + return errors.Wrap( + appel3(), + errors.WithDetail("missing required role"), + errors.WithProperty("Role", "Reader"), + errors.WithProperty("User", "john.doe"), + errors.WithIdentifier(12), + ) +} + +func appel3() error { + // Something went wrong here + return errors.Wrap( + ErrForbidden, + errors.WithIdentifer(2), + errors.WithDetail("permission denied"), + errors.WithProperty("File", "test.txt"), + ) +} +``` + +In the following situation, the program would return +``` +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') +``` \ No newline at end of file