README 2.5 KB

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