mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-04 03:32:25 -06:00 
			
		
		
		
	
		
			
	
	
		
			57 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			57 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								// Copyright 2018 The Go Authors. All rights reserved.
							 | 
						||
| 
								 | 
							
								// Use of this source code is governed by a BSD-style
							 | 
						||
| 
								 | 
							
								// license that can be found in the LICENSE file.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								package xerrors
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"runtime"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// A Frame contains part of a call stack.
							 | 
						||
| 
								 | 
							
								type Frame struct {
							 | 
						||
| 
								 | 
							
									// Make room for three PCs: the one we were asked for, what it called,
							 | 
						||
| 
								 | 
							
									// and possibly a PC for skipPleaseUseCallersFrames. See:
							 | 
						||
| 
								 | 
							
									// https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169
							 | 
						||
| 
								 | 
							
									frames [3]uintptr
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Caller returns a Frame that describes a frame on the caller's stack.
							 | 
						||
| 
								 | 
							
								// The argument skip is the number of frames to skip over.
							 | 
						||
| 
								 | 
							
								// Caller(0) returns the frame for the caller of Caller.
							 | 
						||
| 
								 | 
							
								func Caller(skip int) Frame {
							 | 
						||
| 
								 | 
							
									var s Frame
							 | 
						||
| 
								 | 
							
									runtime.Callers(skip+1, s.frames[:])
							 | 
						||
| 
								 | 
							
									return s
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// location reports the file, line, and function of a frame.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// The returned function may be "" even if file and line are not.
							 | 
						||
| 
								 | 
							
								func (f Frame) location() (function, file string, line int) {
							 | 
						||
| 
								 | 
							
									frames := runtime.CallersFrames(f.frames[:])
							 | 
						||
| 
								 | 
							
									if _, ok := frames.Next(); !ok {
							 | 
						||
| 
								 | 
							
										return "", "", 0
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									fr, ok := frames.Next()
							 | 
						||
| 
								 | 
							
									if !ok {
							 | 
						||
| 
								 | 
							
										return "", "", 0
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return fr.Function, fr.File, fr.Line
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Format prints the stack as error detail.
							 | 
						||
| 
								 | 
							
								// It should be called from an error's Format implementation
							 | 
						||
| 
								 | 
							
								// after printing any other error detail.
							 | 
						||
| 
								 | 
							
								func (f Frame) Format(p Printer) {
							 | 
						||
| 
								 | 
							
									if p.Detail() {
							 | 
						||
| 
								 | 
							
										function, file, line := f.location()
							 | 
						||
| 
								 | 
							
										if function != "" {
							 | 
						||
| 
								 | 
							
											p.Printf("%s\n    ", function)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if file != "" {
							 | 
						||
| 
								 | 
							
											p.Printf("%s:%d\n", file, line)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |