code-intelligence.com/cifuzz@v0.40.0/internal/cmdutils/errors.go (about) 1 package cmdutils 2 3 import ( 4 stdErrors "errors" 5 "fmt" 6 "io" 7 "os/exec" 8 "path/filepath" 9 "strings" 10 "syscall" 11 12 "github.com/pkg/errors" 13 ) 14 15 var ErrSilent = WrapSilentError(stdErrors.New("SilentError")) 16 17 // SilentError indicates that the error message should not be printed 18 // when the error is handled. 19 type SilentError struct { 20 err error 21 } 22 23 func (e SilentError) Error() string { 24 return e.err.Error() 25 } 26 27 func (e SilentError) Unwrap() error { 28 return e.err 29 } 30 31 // WrapSilentError wraps an existing error into a SilentError to avoid 32 // having the error message printed when the error is handled. 33 func WrapSilentError(err error) error { 34 return &SilentError{err} 35 } 36 37 // IncorrectUsageError indicates that the command wasn't used correctly, 38 // for example because required arguments are missing. 39 // When an IncorrectUsageError is handled, the usage message should be 40 // printed. 41 type IncorrectUsageError struct { 42 err error 43 } 44 45 func (e IncorrectUsageError) Error() string { 46 return e.err.Error() 47 } 48 49 func (e IncorrectUsageError) Unwrap() error { 50 return e.err 51 } 52 53 // WrapIncorrectUsageError wraps an existing error into a 54 // IncorrectUsageError to have the usage message printed when the error 55 // is handled. 56 func WrapIncorrectUsageError(err error) error { 57 return &IncorrectUsageError{err} 58 } 59 60 func NewSignalError(signal syscall.Signal) *SignalError { 61 return &SignalError{signal} 62 } 63 64 type SignalError struct { 65 Signal syscall.Signal 66 } 67 68 func (e SignalError) Error() string { 69 return fmt.Sprintf("terminated by signal %d (%s)", int(e.Signal), e.Signal.String()) 70 } 71 72 // CouldBeSandboxError indicates that the error might have been caused 73 // by the sandbox restricting access. When a CouldBeSandboxError is 74 // handled, a message should be printed which suggests to disable the 75 // sandbox if its not needed. 76 type CouldBeSandboxError struct { 77 err error 78 } 79 80 func (e CouldBeSandboxError) Error() string { 81 return e.err.Error() 82 } 83 84 func (e CouldBeSandboxError) Unwrap() error { 85 return e.err 86 } 87 88 // WrapCouldBeSandboxError wraps an existing error into a 89 // CouldBeSandboxError to hint on disabling the sandbox when the error 90 // is handled. 91 func WrapCouldBeSandboxError(err error) error { 92 return &CouldBeSandboxError{err} 93 } 94 95 // ExecError includes information about the exec.Cmd which failed in the 96 // error message. 97 type ExecError struct { 98 err error 99 cmd *exec.Cmd 100 } 101 102 func (e *ExecError) msg() string { 103 var exitErr *exec.ExitError 104 if errors.As(e.err, &exitErr) { 105 stderr := string(exitErr.Stderr) 106 if stderr != "" && !strings.HasSuffix(stderr, "\n") { 107 stderr += "\n" 108 } 109 return fmt.Sprintf("%s%s", stderr, filepath.Base(e.cmd.Args[0])) 110 } 111 return "" 112 } 113 114 func (e *ExecError) Error() string { 115 return fmt.Sprintf("%s: %s\n", e.msg(), e.err.Error()) 116 } 117 118 func (e *ExecError) Format(s fmt.State, verb rune) { 119 switch verb { 120 case 'v': 121 if s.Flag('+') { 122 _, _ = fmt.Fprintf(s, "%s: %+v\n", e.msg(), e.err) 123 return 124 } 125 fallthrough 126 case 's', 'q': 127 _, _ = io.WriteString(s, e.Error()) 128 } 129 } 130 131 func (e *ExecError) Unwrap() error { 132 return e.err 133 } 134 135 // WrapExecError wraps an existing error into an ExecError to include 136 // information about the exec.Cmd which failed in the error message. 137 func WrapExecError(err error, cmd *exec.Cmd) error { 138 return &ExecError{err, cmd} 139 }