vbe*_*nar 4 error-handling web-applications go
我正在用Go编写我的Web应用程序.我想将大多数错误从API转换为恐慌,然后在更高级别的函数中捕获这些恐慌,记录它们并将错误页面返回给用户.
像这样的东西:
func Handler(body func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(responseWriter http.ResponseWriter, request *http.Request) {
defer recoverIfPanic(responseWriter, request)
body(responseWriter, request)
}
}
func recoverIfPanic(responseWriter http.ResponseWriter, request *http.Request) {
reason := recover()
if reason == nil {
return
}
// log and return http error
}
func PanicIf(err error, httpStatus int, description string) {
if error != nil {
panic(MyPanicStruct{err: err, httpStatus: httpStatus, description: description})
}
}
Run Code Online (Sandbox Code Playgroud)
在我的实际代码中
result, err := SomeApi(...)
PanicIf(err, http.StatusInternalServerError, "SomeApi")
Run Code Online (Sandbox Code Playgroud)
在99%的情况下,我无法做任何合理的事情,例如SQL Server返回意外错误或文件系统中缺少文件,我只想记录这种情况并将错误返回给用户.所以我看不出任何理由我应该手动返回"错误"展开堆栈,实际上我将丢失堆栈跟踪和上下文,并且找到错误原因会更加困难.
有什么我想念的,所以这种方法不会有效吗?似乎大多数Go文章建议不要使用恐慌/恢复,但我不明白为什么.它看起来与Java(和类似语言)中的旧的throw-catch机制完全相同,并且它非常适合Web应用程序.
Von*_*onC 10
有什么我想念的,所以这种方法不会有效吗?
今天(!)2014年11月4日由Dave Cheney在" Error handling vs. exceptions redux "中讨论
与三十年前一样,C++异常仍然像安全一样难以安全使用.当你的调用堆栈的任何部分可以在没有警告的情况下爆炸时,难怪有这么多的C++商店强制要求不使用异常.
它指的是" 为什么Go得到正常的例外 "(2012年,在Go1.0之前,但今天仍然有效):
Go确实有一个叫做的设施
panic,如果你足够眯眼,你可能会想到恐慌和扔一样,但你错了.
当你抛出和异常时,你就会成为调用者的问题
throw new SomeoneElsesProblem();
Run Code Online (Sandbox Code Playgroud)
例如,在C++中,当您无法从a转换
enum为string等效时,或者在从字符串解析日期时使用Java时,可能会抛出异常.
在互联网连接的世界中,网络中的每个输入都必须被认为是敌对的,是不是将字符串解析成日期非常特殊?当然不是.当你在Go中恐慌时,你会吓坏,这不是别人的问题,而是游戏胜过男人.
panic("inconceivable")
Run Code Online (Sandbox Code Playgroud)
panics对你的程序来说总是致命的.
在惊慌中你永远不会认为你的来电者可以解决问题.因此,恐慌仅用于特殊情况,代码无法使用,或任何集成代码的人继续使用.不在Go中包含例外的决定是其简单性和正交性的一个例子.使用多个返回值和一个简单的约定,Go解决了让程序员知道什么时候出错的问题,并为真正特殊的事情保留恐慌.
其他使用的方法err在官方维基页面" Error handling and Go "中讨论.
话虽这么说,文章" 延迟,恐慌和恢复 "确实提到了恐慌(json包,(d *decodeState) unmarshal方法)的真实案例,并添加:
Go库中的约定是即使包在内部使用panic,其外部API仍然会显示明确的错误返回值.
因此,如果您使用恐慌严格来说是内部恐慌,那就可以了.