<p>I'm currently working on a little application and I build it on my development machine.</p>
<p>When my compiled binary panics on another computer, it shows the stacktrace with filepaths from my dev machine (e.g. "C:/Users/micro/go/src/go.iondynamics.net/siteMgr/srv/session/session.go:65 +0x13c")</p>
<p>Is there a way to strip these during compilation to something like "GOPATH/src/go.iondynamics.net/siteMgr/srv/session/session.go:65 +0x13c"
or
"GOROOT/src/net/http/server.go:1472 +0xf2e"?</p>
<hr/>**评论:**<br/><br/>dlsniper: <pre><p>As far as I know this is not currently possible from the compiler. Maybe you can search in the Go issues to see if there's anything there or open a new issue for this. However I think it is useful to have the full path as GOPATH can be a collection of paths and then it wouldn't be clear where the file comes from. I guess a simple tool could also change this in the logs if you really need this</p></pre>KEANO_: <pre><p>I agree for debugging purposes. A full stacktrace incl full path is pretty helpful. </p>
<p>But in production-mode a less verbose output is imo preferable (or even better there shouldn't be panics at all :D)</p></pre>dlsniper: <pre><p>I guess the question is: what if the panic happens in production? If you do want this why not write a simple wrapper / processor for your logs and that's it :)</p></pre>KEANO_: <pre><p>My main() now defers a function with recover() and handles panics gracefully without a stack trace at all</p></pre>dlsniper: <pre><p>Please think twice before going down this road. Rarely there are cases where you can handle gracefully a panic. If the app still exists the that's good. For me losing the ability to trace the error would be equally important. </p></pre>KEANO_: <pre><p>I've added this to my main()</p>
<pre><code>if !*debug {
defer func() {
if r := recover(); r != nil {
idl.Emerg(r)
}
}()
}
</code></pre>
<p>If it's in production mode it "catches" all panics and keeps a log of the error via idl (which is a logging package)</p>
<p>Do you think this is bad practice?</p>
<p>edit: idl.Emerg calls os.Exit(1) after handling all log-events</p></pre>dlsniper: <pre><p>If you call exit that's a good thing. Keep in mind that panics may occur because the memory allocator ran out of space and other such issues</p></pre>cheesechoker: <pre><p>More of a workaround than a solution, but... </p>
<p>You could build your app inside a virtual machine (or Docker container) where the source code lives in <code>/src</code> or whatever folder path you prefer.</p></pre>KEANO_: <pre><p>I thought about that, too.
But this method is overkill for my tiny app.</p></pre>SportingSnow21: <pre><p>If you have a specific function that you're hacking, you can put a cleanup defer in it. It's not terribly pretty, but it will clean up the stack traces:</p>
<pre><code>defer func() {
if r := recover(); r!=nil{
log.Println("Recovered error: ", r)
// Get stack trace
buf := make([]byte, 4096)
buf = buf[:runtime.Stack(buf, false)]
// Clean up stack trace
buf = bytes.Replace(buf, []byte(os.GetEnv("GOPATH")), []byte("GOPATH"), -1)
buf = bytes.Replace(buf, []byte(os.GetEnv("GOROOT")), []byte("GOROOT"), -1)
// Print stack trace
log.Println(string(buf))
}
}
</code></pre></pre>kavehmz: <pre><p>If you just want to have less information, one way is to define a "recover" in your main function.</p>
<pre><code>package main
import "fmt"
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("There was an erorr ", r)
}
}()
b := 0
a := 1 / b
fmt.Println(a, b)
}
</code></pre>
<p><a href="https://play.golang.org/p/BHQ6-UWKx-" rel="nofollow">https://play.golang.org/p/BHQ6-UWKx-</a></p>
<p>Try to add and remove defer section and see what happens.</p>
<p>Another way is to set the GOTRACEBACK=none in your environment.</p>
<p>You can find more about it here:</p>
<p><a href="https://golang.org/pkg/runtime/#GOTRACEBACK" rel="nofollow">https://golang.org/pkg/runtime/#GOTRACEBACK</a> </p></pre>KEANO_: <pre><p>I've read about GOTRACEBACK, but it is evaluated at runtime - not compilation.</p>
<p>But recover() is pretty much the perfect solution. Thank you :)
I always thought that the defer/recover section has to be in the same scope as the panic.</p>
<p>So recover() and panics are somewhat like Java's catch-blocks and exceptions? Panics bubble up more than one scope... </p>
<p>edit: manners</p></pre>kavehmz: <pre><p>It is as you say kinda similar to exceptions, in a way that it can give us control over a "panic".</p>
<p>But please be careful as how you use "recover". I is kinda considered bad in Go style.</p>
<p>Your case seems to be actually one of the situations that it might make sense to use "recover".</p>
<p><a href="https://golang.org/ref/spec#Handling_panics" rel="nofollow">https://golang.org/ref/spec#Handling_panics</a></p></pre>KEANO_: <pre><p>That was another reason why I didn't dive into the panic/recover mechanics, yet.
I'm not going to switch to panics. I'll stick to returning error-Interface</p>
<p>But in this special case my main() now defers a recover block :) Thanks again</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传