• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.appveyor/H27-Mar-2018-

.circleci/H27-Mar-2018-

LICENSEH A D27-Mar-20181.2 KiB

READMEH A D27-Mar-20182.5 KiB

warnings.goH A D27-Mar-20185.4 KiB

warnings_test.goH A D27-Mar-20181.9 KiB

README

1Package warnings implements error handling with non-fatal errors (warnings).
2
3import path:   "gopkg.in/warnings.v0"
4package docs:  https://godoc.org/gopkg.in/warnings.v0
5issues:        https://github.com/go-warnings/warnings/issues
6pull requests: https://github.com/go-warnings/warnings/pulls
7
8A recurring pattern in Go programming is the following:
9
10 func myfunc(params) error {
11     if err := doSomething(...); err != nil {
12         return err
13     }
14     if err := doSomethingElse(...); err != nil {
15         return err
16     }
17     if ok := doAnotherThing(...); !ok {
18         return errors.New("my error")
19     }
20     ...
21     return nil
22 }
23
24This pattern allows interrupting the flow on any received error. But what if
25there are errors that should be noted but still not fatal, for which the flow
26should not be interrupted? Implementing such logic at each if statement would
27make the code complex and the flow much harder to follow.
28
29Package warnings provides the Collector type and a clean and simple pattern
30for achieving such logic. The Collector takes care of deciding when to break
31the flow and when to continue, collecting any non-fatal errors (warnings)
32along the way. The only requirement is that fatal and non-fatal errors can be
33distinguished programmatically; that is a function such as
34
35 IsFatal(error) bool
36
37must be implemented. The following is an example of what the above snippet
38could look like using the warnings package:
39
40 import "gopkg.in/warnings.v0"
41
42 func isFatal(err error) bool {
43     _, ok := err.(WarningType)
44     return !ok
45 }
46
47 func myfunc(params) error {
48     c := warnings.NewCollector(isFatal)
49     c.FatalWithWarnings = true
50     if err := c.Collect(doSomething()); err != nil {
51         return err
52     }
53     if err := c.Collect(doSomethingElse(...)); err != nil {
54         return err
55     }
56     if ok := doAnotherThing(...); !ok {
57         if err := c.Collect(errors.New("my error")); err != nil {
58             return err
59         }
60     }
61     ...
62     return c.Done()
63 }
64
65For an example of a non-trivial code base using this library, see
66gopkg.in/gcfg.v1
67
68Rules for using warnings
69
70 - ensure that warnings are programmatically distinguishable from fatal
71   errors (i.e. implement an isFatal function and any necessary error types)
72 - ensure that there is a single Collector instance for a call of each
73   exported function
74 - ensure that all errors (fatal or warning) are fed through Collect
75 - ensure that every time an error is returned, it is one returned by a
76   Collector (from Collect or Done)
77 - ensure that Collect is never called after Done
78