// This function handles a panic in a json API action invocation. // It cleans up the stack trace, logs it, and responds with an error json message. func handleInvocationPanicJson(c *revel.Controller, err interface{}) { // User Initiated panic with error response doesn't need to print the whole stack trace. if errResponse, ok := err.(*JsonErrorResponder); ok { c.Result = JsonErrorResult{errResponse} } else if errResponse, ok := err.(JsonErrorResponder); ok { c.Result = JsonErrorResult{&errResponse} } else { // System initiated panic. Use a JSON error response as we shouldn't // be returning HTML for a JSON defined API. error := revel.NewErrorFromPanic(err) revel.ERROR.Print(err, "\n", error.Stack) if error == nil { revel.ERROR.Print(err, "\n", string(debug.Stack())) } else { revel.ERROR.Print(err, "\n", error.Stack) } var JsonErrorResponder = PanicResponseFactory(err) c.Result = JsonErrorResult{&JsonErrorResponder} } }
func BusinessPanicFilter(c *revel.Controller, fc []revel.Filter) { defer func() { if x := recover(); x != nil { if reflect.TypeOf(x).Name() == "BusinessError" { err := x.(BusinessError) c.Response.ContentType = "application/json; charset=utf-8" c.Result = c.RenderJson(map[string]interface{}{ "success": false, "code": err.Code, "message": err.Error(), }) } else { if revel.Config.StringDefault("mode.dev", "true") != "true" { log.Print(x, "\n", string(debug.Stack())) } panic(x) } } }() fc[0](c, fc[1:]) }