GetOneLineSource extracts the file/line/function information of the topmost caller in the innermost recorded stack trace. The filename is simplified to remove the path prefix. This is used e.g. to populate the "source" field in PostgreSQL errors.
(err error)
| 28 | // This is used e.g. to populate the "source" field in |
| 29 | // PostgreSQL errors. |
| 30 | func GetOneLineSource(err error) (file string, line int, fn string, ok bool) { |
| 31 | // We want the innermost entry: start by recursing. |
| 32 | if c := errbase.UnwrapOnce(err); c != nil { |
| 33 | if file, line, fn, ok = GetOneLineSource(c); ok { |
| 34 | return |
| 35 | } |
| 36 | } |
| 37 | // If we reach this point, we haven't found anything in the cause so |
| 38 | // far. Look at the current level. |
| 39 | |
| 40 | // If we have a stack trace in the style of github.com/pkg/errors |
| 41 | // (either from there or our own withStack), use it. |
| 42 | if st, ok := err.(errbase.StackTraceProvider); ok { |
| 43 | return getOneLineSourceFromPkgStack(st.StackTrace()) |
| 44 | } |
| 45 | |
| 46 | // If we have flattened a github.com/pkg/errors-style stack |
| 47 | // trace to a string, it will happen in the error's safe details |
| 48 | // and we need to parse it. |
| 49 | if sd, ok := err.(errbase.SafeDetailer); ok { |
| 50 | details := sd.SafeDetails() |
| 51 | if len(details) > 0 { |
| 52 | switch errbase.GetTypeKey(err) { |
| 53 | case pkgFundamental, pkgWithStackName, ourWithStackName: |
| 54 | return getOneLineSourceFromPrintedStack(details[0]) |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | // No conversion available - no stack trace. |
| 60 | return "", 0, "", false |
| 61 | } |
| 62 | |
| 63 | func getOneLineSourceFromPkgStack( |
| 64 | st errbase.StackTrace, |
searching dependent graphs…