diff --git a/apiserver/controllers/block.go b/apiserver/controllers/block.go index 6e4dde6c4..6f0099697 100644 --- a/apiserver/controllers/block.go +++ b/apiserver/controllers/block.go @@ -38,10 +38,13 @@ func GetBlockByHashHandler(blockHash string) (interface{}, *utils.HandlerError) } block := &models.Block{} - db.Where(&models.Block{BlockHash: blockHash}).Preload("AcceptingBlock").First(block) - if block.ID == 0 { + dbResult := db.Where(&models.Block{BlockHash: blockHash}).Preload("AcceptingBlock").First(block) + if dbResult.RecordNotFound() && len(dbResult.GetErrors()) == 1 { return nil, utils.NewHandlerError(http.StatusNotFound, "No block with the given block hash was found.") } + if len(dbResult.GetErrors()) > 0 { + return nil, utils.NewHandlerErrorFromDBErrors("Some errors where encountered when loading transactions from the database:", dbResult.GetErrors()) + } return convertBlockModelToBlockResponse(block), nil } diff --git a/apiserver/controllers/transaction.go b/apiserver/controllers/transaction.go index 31d3f30f3..696d894ff 100644 --- a/apiserver/controllers/transaction.go +++ b/apiserver/controllers/transaction.go @@ -28,10 +28,13 @@ func GetTransactionByIDHandler(txID string) (interface{}, *utils.HandlerError) { tx := &models.Transaction{} query := db.Where(&models.Transaction{TransactionID: txID}) - addTxPreloadedFields(query).First(&tx) - if tx.ID == 0 { + dbResult := addTxPreloadedFields(query).First(&tx) + if dbResult.RecordNotFound() && len(dbResult.GetErrors()) == 1 { return nil, utils.NewHandlerError(http.StatusNotFound, "No transaction with the given txid was found.") } + if len(dbResult.GetErrors()) > 0 { + return nil, utils.NewHandlerErrorFromDBErrors("Some errors where encountered when loading transaction from the database:", dbResult.GetErrors()) + } return convertTxModelToTxResponse(tx), nil } @@ -49,10 +52,13 @@ func GetTransactionByHashHandler(txHash string) (interface{}, *utils.HandlerErro tx := &models.Transaction{} query := db.Where(&models.Transaction{TransactionHash: txHash}) - addTxPreloadedFields(query).First(&tx) - if tx.ID == 0 { + dbResult := addTxPreloadedFields(query).First(&tx) + if dbResult.RecordNotFound() && len(dbResult.GetErrors()) == 1 { return nil, utils.NewHandlerError(http.StatusNotFound, "No transaction with the given txhash was found.") } + if len(dbResult.GetErrors()) > 0 { + return nil, utils.NewHandlerErrorFromDBErrors("Some errors where encountered when loading transaction from the database:", dbResult.GetErrors()) + } return convertTxModelToTxResponse(tx), nil } @@ -81,7 +87,10 @@ func GetTransactionsByAddressHandler(address string, skip uint64, limit uint64) Limit(limit). Offset(skip). Order("`transactions`.`id` ASC") - addTxPreloadedFields(query).Find(&txs) + dbErrors := addTxPreloadedFields(query).Find(&txs).GetErrors() + if len(dbErrors) > 0 { + return nil, utils.NewHandlerErrorFromDBErrors("Some errors where encountered when loading transactions from the database:", dbErrors) + } txResponses := make([]*transactionResponse, len(txs)) for i, tx := range txs { txResponses[i] = convertTxModelToTxResponse(tx) @@ -97,11 +106,14 @@ func GetUTXOsByAddressHandler(address string) (interface{}, *utils.HandlerError) } var transactionOutputs []*models.TransactionOutput - db. + dbErrors := db. Joins("LEFT JOIN `addresses` ON `addresses`.`id` = `transaction_outputs`.`address_id`"). Where("`addresses`.`address` = ? AND `transaction_outputs`.`is_spent` = 0", address). Preload("Transaction.AcceptingBlock"). - Find(&transactionOutputs) + Find(&transactionOutputs).GetErrors() + if len(dbErrors) > 0 { + return nil, utils.NewHandlerErrorFromDBErrors("Some errors where encountered when loading UTXOs from the database:", dbErrors) + } UTXOsResponses := make([]*transactionOutputResponse, len(transactionOutputs)) for i, transactionOutput := range transactionOutputs { diff --git a/apiserver/utils/error.go b/apiserver/utils/error.go index 8fa16d04e..ff25275f4 100644 --- a/apiserver/utils/error.go +++ b/apiserver/utils/error.go @@ -1,6 +1,10 @@ package utils -import "net/http" +import ( + "fmt" + "net/http" + "strings" +) // HandlerError is an error returned from // a rest route handler or a middleware. @@ -39,3 +43,21 @@ func NewHandlerErrorWithCustomClientMessage(code int, message, clientMessage str func NewInternalServerHandlerError(message string) *HandlerError { return NewHandlerErrorWithCustomClientMessage(http.StatusInternalServerError, message, http.StatusText(http.StatusInternalServerError)) } + +// NewErrorFromDBErrors takes a slice of database errors and a prefix, and +// returns an error with all of the database errors formatted to one string with +// the given prefix +func NewErrorFromDBErrors(prefix string, dbErrors []error) error { + dbErrorsStrings := make([]string, len(dbErrors)) + for i, dbErr := range dbErrors { + dbErrorsStrings[i] = fmt.Sprintf("\"%s\"", dbErr) + } + return fmt.Errorf("%s [%s]", prefix, strings.Join(dbErrorsStrings, ",")) +} + +// NewHandlerErrorFromDBErrors takes a slice of database errors and a prefix, and +// returns an HandlerError with error code http.StatusInternalServerError with +// all of the database errors formatted to one string with the given prefix +func NewHandlerErrorFromDBErrors(prefix string, dbErrors []error) *HandlerError { + return NewInternalServerHandlerError(NewErrorFromDBErrors(prefix, dbErrors).Error()) +}