decred.org/dcrdex@v1.0.5/dex/errors.go (about) 1 // This code is available on the terms of the project LICENSE.md file, 2 // also available online at https://blueoakcouncil.org/license/1.0.0. 3 4 package dex 5 6 // ErrorKind identifies a kind of error that can be used to define new errors 7 // via const SomeError = dex.ErrorKind("something"). 8 type ErrorKind string 9 10 // Error satisfies the error interface and prints human-readable errors. 11 func (e ErrorKind) Error() string { 12 return string(e) 13 } 14 15 // Error pairs an error with details. 16 type Error struct { 17 wrapped error 18 detail string 19 } 20 21 // Error satisfies the error interface, combining the wrapped error message with 22 // the details. 23 func (e Error) Error() string { 24 return e.wrapped.Error() + ": " + e.detail 25 } 26 27 // Unwrap returns the wrapped error, allowing errors.Is and errors.As to work. 28 func (e Error) Unwrap() error { 29 return e.wrapped 30 } 31 32 // NewError wraps the provided Error with details in a Error, facilitating the 33 // use of errors.Is and errors.As via errors.Unwrap. 34 func NewError(err error, detail string) Error { 35 return Error{ 36 wrapped: err, 37 detail: detail, 38 } 39 } 40 41 // ErrorCloser is used to synchronize shutdown when an error is encountered in a 42 // multi-step process. After each successful step, a shutdown routine can be 43 // scheduled with Add. If Success is not signaled before Done, the shutdown 44 // routines will be run in the reverse order that they are added. 45 type ErrorCloser struct { 46 closers []func() error 47 } 48 49 // NewErrorCloser creates a new ErrorCloser. 50 func NewErrorCloser() *ErrorCloser { 51 return &ErrorCloser{ 52 closers: make([]func() error, 0, 3), 53 } 54 } 55 56 // Add adds a new function to the queue. If Success is not called before Done, 57 // the Add'ed functions will be run in the reverse order that they were added. 58 func (e *ErrorCloser) Add(closer func() error) { 59 e.closers = append(e.closers, closer) 60 } 61 62 // Success cancels the running of any Add'ed functions. 63 func (e *ErrorCloser) Success() { 64 e.closers = nil 65 } 66 67 // Done signals that the ErrorClose can run its registered functions if success 68 // has not yet been flagged. 69 func (e *ErrorCloser) Done(log Logger) { 70 for i := len(e.closers) - 1; i >= 0; i-- { 71 if err := e.closers[i](); err != nil { 72 log.Errorf("error running shutdown function %d: %v", i, err) 73 } 74 } 75 } 76 77 // Copy creates a shallow copy of the ErrorCloser. 78 func (e *ErrorCloser) Copy() *ErrorCloser { 79 return &ErrorCloser{ 80 closers: e.closers, 81 } 82 }