[NOD-325] Enable separate error messages for logging and client (#406)

* [NOD-325] Enable separate error messages for logging and client

* [NOD-325] Add json annotation to clientError
This commit is contained in:
Ori Newman 2019-09-16 13:26:05 +03:00 committed by stasatdaglabs
parent 502b510ccd
commit 31ccedf136
5 changed files with 45 additions and 14 deletions

View File

@ -20,7 +20,7 @@ func GetBlockByHashHandler(blockHash string) (interface{}, *utils.HandlerError)
db, err := database.DB() db, err := database.DB()
if err != nil { if err != nil {
return nil, utils.NewHandlerError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return nil, utils.NewInternalServerHandlerError(err.Error())
} }
block := &models.Block{} block := &models.Block{}

View File

@ -23,7 +23,7 @@ func GetTransactionByIDHandler(txID string) (interface{}, *utils.HandlerError) {
db, err := database.DB() db, err := database.DB()
if err != nil { if err != nil {
return nil, utils.NewHandlerError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return nil, utils.NewInternalServerHandlerError(err.Error())
} }
tx := &models.Transaction{} tx := &models.Transaction{}
@ -44,7 +44,7 @@ func GetTransactionByHashHandler(txHash string) (interface{}, *utils.HandlerErro
db, err := database.DB() db, err := database.DB()
if err != nil { if err != nil {
return nil, utils.NewHandlerError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return nil, utils.NewInternalServerHandlerError(err.Error())
} }
tx := &models.Transaction{} tx := &models.Transaction{}
@ -66,7 +66,7 @@ func GetTransactionsByAddressHandler(address string, skip uint64, limit uint64)
db, err := database.DB() db, err := database.DB()
if err != nil { if err != nil {
return nil, utils.NewHandlerError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return nil, utils.NewInternalServerHandlerError(err.Error())
} }
txs := []*models.Transaction{} txs := []*models.Transaction{}
@ -93,7 +93,7 @@ func GetTransactionsByAddressHandler(address string, skip uint64, limit uint64)
func GetUTXOsByAddressHandler(address string) (interface{}, *utils.HandlerError) { func GetUTXOsByAddressHandler(address string) (interface{}, *utils.HandlerError) {
db, err := database.DB() db, err := database.DB()
if err != nil { if err != nil {
return nil, utils.NewHandlerError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return nil, utils.NewInternalServerHandlerError(err.Error())
} }
var transactionOutputs []*models.TransactionOutput var transactionOutputs []*models.TransactionOutput

View File

@ -1,6 +1,7 @@
package server package server
import ( import (
"fmt"
"github.com/daglabs/btcd/apiserver/utils" "github.com/daglabs/btcd/apiserver/utils"
"net/http" "net/http"
"runtime/debug" "runtime/debug"
@ -31,9 +32,10 @@ func recoveryMiddleware(h http.Handler) http.Handler {
defer func() { defer func() {
recoveryErr := recover() recoveryErr := recover()
if recoveryErr != nil { if recoveryErr != nil {
log.Criticalf("Fatal error: %s", recoveryErr) recoveryErrStr := fmt.Sprintf("%s", recoveryErr)
log.Criticalf("Fatal error: %s", recoveryErrStr)
log.Criticalf("Stack trace: %s", debug.Stack()) log.Criticalf("Stack trace: %s", debug.Stack())
sendErr(ctx, w, utils.NewHandlerError(http.StatusInternalServerError, "A server error occurred.")) sendErr(ctx, w, utils.NewInternalServerHandlerError(recoveryErrStr))
} }
}() }()
h.ServeHTTP(w, r) h.ServeHTTP(w, r)

View File

@ -40,11 +40,19 @@ func makeHandler(
} }
} }
type clientError struct {
ErrorCode int `json:"errorCode"`
ErrorMessage string `json:"errorMessage"`
}
func sendErr(ctx *utils.APIServerContext, w http.ResponseWriter, hErr *utils.HandlerError) { func sendErr(ctx *utils.APIServerContext, w http.ResponseWriter, hErr *utils.HandlerError) {
errMsg := fmt.Sprintf("got error: %s", hErr) errMsg := fmt.Sprintf("got error: %s", hErr)
ctx.Warnf(errMsg) ctx.Warnf(errMsg)
w.WriteHeader(hErr.ErrorCode) w.WriteHeader(hErr.Code)
sendJSONResponse(w, hErr) sendJSONResponse(w, &clientError{
ErrorCode: hErr.Code,
ErrorMessage: hErr.ClientMessage,
})
} }
func sendJSONResponse(w http.ResponseWriter, response interface{}) { func sendJSONResponse(w http.ResponseWriter, response interface{}) {

View File

@ -1,20 +1,41 @@
package utils package utils
import "net/http"
// HandlerError is an error returned from // HandlerError is an error returned from
// a rest route handler or a middleware. // a rest route handler or a middleware.
type HandlerError struct { type HandlerError struct {
ErrorCode int Code int
ErrorMessage string Message string
ClientMessage string
} }
func (hErr *HandlerError) Error() string { func (hErr *HandlerError) Error() string {
return hErr.ErrorMessage return hErr.Message
} }
// NewHandlerError returns a HandlerError with the given code and message. // NewHandlerError returns a HandlerError with the given code and message.
func NewHandlerError(code int, message string) *HandlerError { func NewHandlerError(code int, message string) *HandlerError {
return &HandlerError{ return &HandlerError{
ErrorCode: code, Code: code,
ErrorMessage: message, Message: message,
ClientMessage: message,
} }
} }
// NewHandlerErrorWithCustomClientMessage returns a HandlerError with
// the given code, message and client error message.
func NewHandlerErrorWithCustomClientMessage(code int, message, clientMessage string) *HandlerError {
return &HandlerError{
Code: code,
Message: message,
ClientMessage: clientMessage,
}
}
// NewInternalServerHandlerError returns a HandlerError with
// the given message, and the http.StatusInternalServerError
// status text as client message.
func NewInternalServerHandlerError(message string) *HandlerError {
return NewHandlerErrorWithCustomClientMessage(http.StatusInternalServerError, message, http.StatusText(http.StatusInternalServerError))
}