You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.5 KiB

  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. For an example of a non-trivial code base using this library, see
  55. gopkg.in/gcfg.v1
  56. Rules for using warnings
  57. - ensure that warnings are programmatically distinguishable from fatal
  58. errors (i.e. implement an isFatal function and any necessary error types)
  59. - ensure that there is a single Collector instance for a call of each
  60. exported function
  61. - ensure that all errors (fatal or warning) are fed through Collect
  62. - ensure that every time an error is returned, it is one returned by a
  63. Collector (from Collect or Done)
  64. - ensure that Collect is never called after Done