| 289 | } |
| 290 | |
| 291 | func errorStack(err error) []string { |
| 292 | if err == nil { |
| 293 | return nil |
| 294 | } |
| 295 | |
| 296 | // We want the first error first |
| 297 | var lines []string |
| 298 | for { |
| 299 | var buff []byte |
| 300 | if err, ok := err.(Locationer); ok { |
| 301 | file, line := err.Location() |
| 302 | // Strip off the leading GOPATH/src path elements. |
| 303 | if file != "" { |
| 304 | buff = append(buff, fmt.Sprintf("%s:%d", file, line)...) |
| 305 | buff = append(buff, ": "...) |
| 306 | } |
| 307 | } |
| 308 | if cerr, ok := err.(wrapper); ok { |
| 309 | message := cerr.Message() |
| 310 | buff = append(buff, message...) |
| 311 | // If there is a cause for this error, and it is different to the cause |
| 312 | // of the underlying error, then output the error string in the stack trace. |
| 313 | var cause error |
| 314 | if err1, ok := err.(causer); ok { |
| 315 | cause = err1.Cause() |
| 316 | } |
| 317 | err = cerr.Underlying() |
| 318 | if cause != nil && !sameError(Cause(err), cause) { |
| 319 | if message != "" { |
| 320 | buff = append(buff, ": "...) |
| 321 | } |
| 322 | buff = append(buff, cause.Error()...) |
| 323 | } |
| 324 | } else { |
| 325 | buff = append(buff, err.Error()...) |
| 326 | err = nil |
| 327 | } |
| 328 | lines = append(lines, string(buff)) |
| 329 | if err == nil { |
| 330 | break |
| 331 | } |
| 332 | } |
| 333 | // reverse the lines to get the original error, which was at the end of |
| 334 | // the list, back to the start. |
| 335 | var result []string |
| 336 | for i := len(lines); i > 0; i-- { |
| 337 | result = append(result, lines[i-1]) |
| 338 | } |
| 339 | return result |
| 340 | } |
| 341 | |
| 342 | // Unwrap is a proxy for the Unwrap function in Go's standard `errors` library |
| 343 | // (pkg.go.dev/errors). |