恐慌处理或发生了什么
panic handling or what has happend
我不明白处理恐慌的最佳方法是什么。我可以编写自己的 panic("bad data or empty source")
并且我将确定代码在这个确切位置失败的输出,但是如何处理不是我的方法中生成的恐慌。
现在我有这样的错误:
C:/gocode/src/github.com/revel/revel/panic.go:26 (0x4975a4) handleInvocationPanic: c.Response.Out.Write(debug.Stack())
C:/gocode/src/github.com/revel/revel/panic.go:12 (0x4b60ca) PanicFilter.func1: handleInvocationPanic(c, err)
c:/go/src/runtime/asm_amd64.s:437 (0x45cc75) call32: CALLFN(·call32, 32)
c:/go/src/runtime/panic.go:423 (0x42ec17) gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
C:/gocode/src/github.com/revel/revel/intercept.go:93 (0x4b6061) InterceptorFilter.func1: panic(err)
c:/go/src/runtime/asm_amd64.s:437 (0x45cc75) call32: CALLFN(·call32, 32)
c:/go/src/runtime/panic.go:423 (0x42ec17) gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
c:/go/src/runtime/panic.go:42 (0x42d280) panicmem: panic(memoryError)
c:/go/src/runtime/signal_windows.go:161 (0x44233d) sigpanic: panicmem()
C:/gocode/src/github.com/oculus/libs/funcs.go:13 (0x4e0ca5) GetDatesInRange: fmt.Println(err.Error())
C:/gocode/src/github.com/oculus/rest/app/controllers/kpi.go:97 (0x4e3b2f) KpiCtrl.GetNoagg: dates, errors := libs.GetDatesInRange(request.Filters.DayStart, request.Filters.DayEnd) :97 (0x4e9f12)
c:/go/src/runtime/asm_amd64.s:437 (0x45cc75) call32: CALLFN(·call32, 32)
c:/go/src/reflect/value.go:432 (0x471591) Value.call: call(frametype, fn, args, uint32(frametype.size), uint32(retOffset))
c:/go/src/reflect/value.go:300 (0x470258) Value.Call: return v.call("Call", in)
C:/gocode/src/github.com/revel/revel/invoker.go:36 (0x496e51) ActionInvoker: resultValue = methodValue.Call(methodArgs)[0]
C:/gocode/src/github.com/revel/revel/compress.go:47 (0x487f89) CompressFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/intercept.go:103 (0x4954b9) InterceptorFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/oculus/rest/app/init.go:37 (0x4e2366) glob.func1: fc[0](c, fc[1:]) // Execute the next filter stage.
C:/gocode/src/github.com/revel/revel/i18n.go:155 (0x4947a3) I18nFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/validation.go:191 (0x4ae27d) ValidationFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/flash.go:46 (0x490ee7) FlashFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/session.go:149 (0x4a914c) SessionFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/params.go:133 (0x499116) ParamsFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/filterconfig.go:208 (0x490a64) FilterConfiguringFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/router.go:474 (0x4a61e6) RouterFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/panic.go:15 (0x4972c8) PanicFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/watcher.go:232 (0x4b512d) glob.func31: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/server.go:50 (0x4a6d95) handleInternal: Filters[0](c, Filters[1:])
C:/gocode/src/github.com/revel/revel/server.go:38 (0x4a68f6) handle: handleInternal(w, r, nil)
c:/go/src/net/http/server.go:1422 (0x57cfe1) HandlerFunc.ServeHTTP: f(w, r)
c:/go/src/net/http/server.go:1862 (0x57f285) serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
c:/go/src/net/http/server.go:1361 (0x57ca85) (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
c:/go/src/runtime/asm_amd64.s:1721 (0x45f121) goexit: BYTE [=10=]x90 // NOP
我应该如何与他们合作,或者如何确定问题出在哪里。这一次对我来说没有意义。
在 Go
中,您可以从恐慌中恢复,其中确实包含恐慌错误消息。恢复后,您可以分析发生恐慌的原因。要从恐慌中恢复,您可以使用 defer
语句,顾名思义,它会延迟语句的执行。这意味着您可以跳过一些事件来挂断系统,这不是一个很好的解决方案。最好的解决方案是捕获错误并适当地处理它们。如果错误发生在某些第三方框架上,则应由其创建者解决。如果不是,您应该检查为什么您的代码出现恐慌。
这里是 panic recover 的代码片段:
defer func() {
if err := recover(); err != nil {
fmt.Printf("Recovered from panic. %s", err)
}
}()
这里是一个简单的示例,说明如何使用构建的紧急和恢复方法:
package main
import "fmt"
func badCall() {
panic("Bad call happend!")
}
func test() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("Panicking %s\n\r" , err)
}
}()
badCall()
fmt.Println("This is never executed!!")
}
func main() {
fmt.Println("Start testing")
test()
fmt.Println("End testing")
}
http://play.golang.org/p/Uz9W76SfRT
如果在延迟函数内调用 recover,堆栈将停止展开并恢复 returns 传递给 panic 的值(作为 interface{}
!)。这意味着您可以将接口作为参数传递给 panic 方法,例如:
type ParseError struct {
Index int // The index into the space-separated list of words.
Word string // The word that generated the parse error.
Error error // The raw error that precipitated this error, if any.
}
// String returns a human-readable error message.
func (e *ParseError) String() string {
return fmt.Sprintf("pkg: error parsing %q as int", e.Word)
}
// ... some code
if err != nil {
panic(&ParseError{idx, field, err})
}
// ... some code
然后可以分析deferred语句中传递的接口
您可以使用这段代码并将其放在每个函数中
defer func() {
if err := recover(); err != nil {
fmt.Println("Panic Occured and Recovered in, Error Info: ", err)
}
}()
试试这个对你有用。
我不明白处理恐慌的最佳方法是什么。我可以编写自己的 panic("bad data or empty source")
并且我将确定代码在这个确切位置失败的输出,但是如何处理不是我的方法中生成的恐慌。
现在我有这样的错误:
C:/gocode/src/github.com/revel/revel/panic.go:26 (0x4975a4) handleInvocationPanic: c.Response.Out.Write(debug.Stack())
C:/gocode/src/github.com/revel/revel/panic.go:12 (0x4b60ca) PanicFilter.func1: handleInvocationPanic(c, err)
c:/go/src/runtime/asm_amd64.s:437 (0x45cc75) call32: CALLFN(·call32, 32)
c:/go/src/runtime/panic.go:423 (0x42ec17) gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
C:/gocode/src/github.com/revel/revel/intercept.go:93 (0x4b6061) InterceptorFilter.func1: panic(err)
c:/go/src/runtime/asm_amd64.s:437 (0x45cc75) call32: CALLFN(·call32, 32)
c:/go/src/runtime/panic.go:423 (0x42ec17) gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
c:/go/src/runtime/panic.go:42 (0x42d280) panicmem: panic(memoryError)
c:/go/src/runtime/signal_windows.go:161 (0x44233d) sigpanic: panicmem()
C:/gocode/src/github.com/oculus/libs/funcs.go:13 (0x4e0ca5) GetDatesInRange: fmt.Println(err.Error())
C:/gocode/src/github.com/oculus/rest/app/controllers/kpi.go:97 (0x4e3b2f) KpiCtrl.GetNoagg: dates, errors := libs.GetDatesInRange(request.Filters.DayStart, request.Filters.DayEnd) :97 (0x4e9f12)
c:/go/src/runtime/asm_amd64.s:437 (0x45cc75) call32: CALLFN(·call32, 32)
c:/go/src/reflect/value.go:432 (0x471591) Value.call: call(frametype, fn, args, uint32(frametype.size), uint32(retOffset))
c:/go/src/reflect/value.go:300 (0x470258) Value.Call: return v.call("Call", in)
C:/gocode/src/github.com/revel/revel/invoker.go:36 (0x496e51) ActionInvoker: resultValue = methodValue.Call(methodArgs)[0]
C:/gocode/src/github.com/revel/revel/compress.go:47 (0x487f89) CompressFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/intercept.go:103 (0x4954b9) InterceptorFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/oculus/rest/app/init.go:37 (0x4e2366) glob.func1: fc[0](c, fc[1:]) // Execute the next filter stage.
C:/gocode/src/github.com/revel/revel/i18n.go:155 (0x4947a3) I18nFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/validation.go:191 (0x4ae27d) ValidationFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/flash.go:46 (0x490ee7) FlashFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/session.go:149 (0x4a914c) SessionFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/params.go:133 (0x499116) ParamsFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/filterconfig.go:208 (0x490a64) FilterConfiguringFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/router.go:474 (0x4a61e6) RouterFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/panic.go:15 (0x4972c8) PanicFilter: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/watcher.go:232 (0x4b512d) glob.func31: fc[0](c, fc[1:])
C:/gocode/src/github.com/revel/revel/server.go:50 (0x4a6d95) handleInternal: Filters[0](c, Filters[1:])
C:/gocode/src/github.com/revel/revel/server.go:38 (0x4a68f6) handle: handleInternal(w, r, nil)
c:/go/src/net/http/server.go:1422 (0x57cfe1) HandlerFunc.ServeHTTP: f(w, r)
c:/go/src/net/http/server.go:1862 (0x57f285) serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
c:/go/src/net/http/server.go:1361 (0x57ca85) (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
c:/go/src/runtime/asm_amd64.s:1721 (0x45f121) goexit: BYTE [=10=]x90 // NOP
我应该如何与他们合作,或者如何确定问题出在哪里。这一次对我来说没有意义。
在 Go
中,您可以从恐慌中恢复,其中确实包含恐慌错误消息。恢复后,您可以分析发生恐慌的原因。要从恐慌中恢复,您可以使用 defer
语句,顾名思义,它会延迟语句的执行。这意味着您可以跳过一些事件来挂断系统,这不是一个很好的解决方案。最好的解决方案是捕获错误并适当地处理它们。如果错误发生在某些第三方框架上,则应由其创建者解决。如果不是,您应该检查为什么您的代码出现恐慌。
这里是 panic recover 的代码片段:
defer func() {
if err := recover(); err != nil {
fmt.Printf("Recovered from panic. %s", err)
}
}()
这里是一个简单的示例,说明如何使用构建的紧急和恢复方法:
package main
import "fmt"
func badCall() {
panic("Bad call happend!")
}
func test() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("Panicking %s\n\r" , err)
}
}()
badCall()
fmt.Println("This is never executed!!")
}
func main() {
fmt.Println("Start testing")
test()
fmt.Println("End testing")
}
http://play.golang.org/p/Uz9W76SfRT
如果在延迟函数内调用 recover,堆栈将停止展开并恢复 returns 传递给 panic 的值(作为 interface{}
!)。这意味着您可以将接口作为参数传递给 panic 方法,例如:
type ParseError struct {
Index int // The index into the space-separated list of words.
Word string // The word that generated the parse error.
Error error // The raw error that precipitated this error, if any.
}
// String returns a human-readable error message.
func (e *ParseError) String() string {
return fmt.Sprintf("pkg: error parsing %q as int", e.Word)
}
// ... some code
if err != nil {
panic(&ParseError{idx, field, err})
}
// ... some code
然后可以分析deferred语句中传递的接口
您可以使用这段代码并将其放在每个函数中
defer func() {
if err := recover(); err != nil {
fmt.Println("Panic Occured and Recovered in, Error Info: ", err)
}
}()
试试这个对你有用。