(ctx context.Context, err error)
| 197 | } |
| 198 | |
| 199 | func (c *Cmd) error(ctx context.Context, err error) error { |
| 200 | if err == nil { |
| 201 | return nil |
| 202 | } |
| 203 | |
| 204 | cmdErr := &cmdError{err: err} |
| 205 | if errors.Is(err, exec.ErrNotFound) { |
| 206 | cmdErr.msg = fmt.Sprintf("nix: %s not found in $PATH", c.Args[0]) |
| 207 | } |
| 208 | |
| 209 | switch { |
| 210 | case errors.Is(ctx.Err(), context.Canceled): |
| 211 | cmdErr.msg = "nix: command canceled" |
| 212 | case errors.Is(ctx.Err(), context.DeadlineExceeded): |
| 213 | cmdErr.msg = "nix: command timed out" |
| 214 | default: |
| 215 | cmdErr.msg = "nix: command error" |
| 216 | } |
| 217 | cmdErr.msg += ": " + c.String() |
| 218 | |
| 219 | var exitErr *exec.ExitError |
| 220 | if errors.As(err, &exitErr) { |
| 221 | if stderr := c.stderrExcerpt(exitErr.Stderr); len(stderr) != 0 { |
| 222 | cmdErr.msg += ": " + stderr |
| 223 | } |
| 224 | if exitErr.Exited() { |
| 225 | cmdErr.msg += fmt.Sprintf(": exit code %d", exitErr.ExitCode()) |
| 226 | return cmdErr |
| 227 | } |
| 228 | if stat, ok := exitErr.Sys().(syscall.WaitStatus); ok && stat.Signaled() { |
| 229 | cmdErr.msg += fmt.Sprintf(": exit due to signal %d (%[1]s)", stat.Signal()) |
| 230 | return cmdErr |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | if !errors.Is(err, ctx.Err()) { |
| 235 | cmdErr.msg += ": " + err.Error() |
| 236 | } |
| 237 | return cmdErr |
| 238 | } |
| 239 | |
| 240 | func (*Cmd) stderrExcerpt(stderr []byte) string { |
| 241 | stderr = bytes.TrimSpace(stderr) |
no test coverage detected