3.3.6.Walkthrough: Implementation of error handling for POST API
如果POST失敗, 只回400是不夠的, 為了讓開發找更能addressing issue, Steps to improve POST error handling
1.Steup the error codes and description for API specific errors
2.Create the template for the error response body
3.Code a utility function for creating the error response
4.Implement the error handling code for POST /vacations
Send back status code for duplicate & vacation errors
建議使用的status code
code 5000: unknown Error
code 6xxx: Any database error such as duplicate keys
code 7xxx: Validation error
module.exports = function (router) {
'use strict';
// CREATE new vacation packages
router.route(URI).post(function (req, res, next) {
console.log("POST Vacations")
//1. Get the data
var doc = req.body;
//2. Call the insert method
db.save(doc, function (err, saved) {
if (err) {
// Creates the error response
// EARLIER it was >>> res.status(400).send("err")
var userError = processMongooseErrors(apiMessages.errors.API_MESSAGE_CREATE_FAILED, "POST", URI, err,{});
res.setHeader('content-type', 'application/json')
res.status(400).send(userError)
} else {
res.send(saved)
}
});
});
}
/**
* Converts the Mongoose validation errors to API specific errors
*/
var processMongooseErrors = function (message, method, endpoint, err,payload) {
var errorList = []
// Check for validation error
if (err.name === 'ValidationError'){
errorList = processValidationErrors(err)
} else if(err.code == 11000){
// it could be database error - 11000 is for duplicate key
errorList.push(apiErrors.errors.PACKAGE_ALREADY_EXISTS)
} else {
var errUnknown = apiErrors.errors.UNKNOWN_ERROR
errUnknown.payload = err
errorList = [apiErrors.errors.UNKNOWN_ERROR]
}
return apiErrors.create(message, method, endpoint, errorList, payload)
}
/**
* Converts Mongoose errors to API specific errors
*/
var processValidationErrors = function (err) {
var errorList = []
// Check if there is an issue with the Num of Nights
if (err.errors.numberOfNights) {
if (err.errors.numberOfNights.kind === apiErrors.kinds.MIN_ERROR
|| err.errors.numberOfNights.kind === apiErrors.kinds.MAX_ERROR
|| err.errors.numberOfNights.kind === apiErrors.kinds.NUMBER_ERROR ) {
errorList.push(apiErrors.errors.FORMAT_NUM_OF_NIGHTS)
}
}
// Check if name of the package is missing
if (err.errors.name) {
if (err.errors.name.kind === apiErrors.kinds.REQUIRED) {
errorList.push(apiErrors.errors.MISSING_PACKAGE_NAME)
}
}
// Check if description of the package is missing
if (err.errors.description) {
if (err.errors.description.kind === apiErrors.kinds.REQUIRED) {
errorList.push(apiErrors.errors.MISSING_PACKAGE_DESCRIPTION)
}
}
return errorList;
}
util/error
1.建立error list物件
2.create方法會回傳text:message, timestamp, method, endpoint, errors, payload
exports.errors = { // This is a catch all error // Ideally this should never be thrown UNKNOWN_ERROR : { code:5000, text:"Unknown error !!!", hints:["Please contact development team wit information on 'how to reproduce this error'. Thank you for your help and support."], info:"http://developer.acme.com/unknownerror" }, PACKAGE_ALREADY_EXISTS :{ code:6000, text:"Vacation package with the provided 'name' already exist", hints:["Please use PUT for update instead of POST"], info:"http://developer.acme.com/errors#6000" }, // All required/missing field errors start with number 7 MISSING_PACKAGE_NAME : { code:7001, text:"Required field vacation 'name' is missing", hints:["Please check that user has provided the non null value for 'name'"], info:"http://developer.acme.com/error#RequiredFields" }, MISSING_PACKAGE_DESCRIPTION : { code:7002, text:"Required field vacation 'description' is missing", hints:["Please check that user has provided the non null value for description"], info:"http://developer.acme.com/error#RequiredFields" } , MISSING_PACKAGE_NUM_OF_NIGHTS : { code:7003, text:"Required field vacation 'number of nights' is missing", hints:["Please check that user has provided a number (between 1 & 31)"], info:"http://developer.acme.com/error#RequiredFields" }, // All format errors begin with 8 FORMAT_NUM_OF_NIGHTS : { code:7004, text:"Number of nights MUST be a number (between 1 & 31)", hints:["Please check that user has provided a numeric value for 'number of nights'"], info:"http://developer.acme.com/error#RequiredFields" } } /** * Utility methods * Creates the error response body to be sent back to the caller */ exports.create = function(message,httpMethod,endpointInformation,errorList,receivedPayload){ return { // Meant for the developer text:message, timestamp:new Date(), // POST, GET .... method:httpMethod, // Endpoint information endpoint:endpointInformation, // An array of all errors errors : errorList, // OPTIONAL - Use only during development payload: receivedPayload } } // Mongoose validation error types exports.kinds = { REQUIRED:"required", NOT_VALID:"notvalid", NUMBER_ERROR:"Number", MIN_ERROR:"min", MAX_ERROR:"max", }
結果
Last updated
Was this helpful?