2017-03-26 2 views
4

RAML 사양 오류로 인해 발신자에게 보낸 응답을 사용자 지정 처리하려고합니다. 지금은 코드가 다음을 수행합니다.Osprey RAML 유효성 검사 오류 처리

const cfg = require("./cfg"); 
const log = require('./logging'); 
const RAML = require('osprey'); 
const startMessage = "My Service started on port " + cfg.SERVER_PORT + " at " + cfg.API_MOUNT_POINT; 

// start an express server 
const start = x => { 
    // server dependencies 
    const fs = require('fs'), 
    express = require('express'), 
    app = express(), 
    router = express.Router(), 
    bodyParser = require('body-parser'), 
    api = require('./api'); 

    RAML.loadFile(cfg.API_SPEC).then(_raml => { 

    app.use(bodyParser.json({ extended: true })); 
    // hide the useless "powered by express" header 
    app.disable('x-powered-by'); 
    // RAML validation 
    app.use(cfg.API_MOUNT_POINT, _raml); 
    app.use(cfg.API_MOUNT_POINT, api); 
    }) 
    .then(v => { 
    app.listen(cfg.SERVER_PORT, function() { 
     log.info(startMessage); 
    }); 
    }) 
    .catch(e => log.error(e)); 
} 

이 방법은 정상적으로 작동하지만 유효성 검사가 실패 할 경우 발신자에게 보내는 응답은 아래와 같습니다.

{ 
    "errors": [ 
    { 
     "type": "json", 
     "dataPath": "redeemtype", 
     "keyword": "required", 
     "schema": true, 
     "message": "Missing required property: redeemtype" 
    } 
    ], 
    "stack": "BadRequestError: Request failed to validate against RAML definition\n at createValidationError (/Volumes/Devel/dollardine/node_modules/osprey-method-handler/osprey-method-handler.js:735:14)\n at ospreyJsonBody (/Volumes/Devel/dollardine/node_modules/osprey-method-handler/osprey-method-handler.js:448:21)\n at handle (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:56:16)\n at dispatch (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:39:20)\n at next (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:37:24)\n at jsonParser (/Volumes/Devel/dollardine/node_modules/body-parser/lib/types/json.js:94:7)\n at handle (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:56:16)\n at dispatch (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:39:20)\n at middleware (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:41:16)\n at /Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:10:16\n at ospreyContentType (/Volumes/Devel/dollardine/node_modules/osprey-method-handler/osprey-method-handler.js:325:17)\n at handle (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:56:16)\n at dispatch (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:39:20)\n at next (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:37:24)\n at ospreyMethodHeader (/Volumes/Devel/dollardine/node_modules/osprey-method-handler/osprey-method-handler.js:262:12)\n at handle (/Volumes/Devel/dollardine/node_modules/compose-middleware/lib/index.js:56:16)" 
} 

위대한 내용이지만 발신자에게이 정보를 모두 보내고 싶지는 않습니다. 로컬로 로그인하고 { "code": 400, "message": "Invalid input"}을 보냈 으면합니다.

오류 응답을 처리 할 수있게 해주는 osprey를 만들려면 어떻게해야합니까?

답변

1

나는 내 자신의 질문에 대한 답을 찾았습니다. 미래에 누군가가 여기에 걸린 경우를 대비해서.

const start = x => { 
    // server dependencies 
    const fs = require('fs'), 
    express = require('express'), 
    app = express(), 
    router = express.Router(), 
    bodyParser = require('body-parser'), 
    api = require('./api'); 

    const ramlConfig = { 
    "server": { 
     "notFoundHandler": false 
    }, 
    "disableErrorInterception": true 
    } 

    osprey.loadFile(cfg.API_SPEC, ramlConfig).then(_raml => { 

    app.use(bodyParser.json({ extended: true })); 
    // hide the useless "powered by express" header 
    app.disable('x-powered-by'); 
    // RAML validation 
    app.use(cfg.API_MOUNT_POINT, _raml); 
    app.use(customNotFoundHandler); 
    app.use(ramlErrorChecker); 


    app.use(cfg.API_MOUNT_POINT, api); 
    //app.use(ramlErrorChecker); 
    }) 
    .then(v => { 
    app.listen(cfg.SERVER_PORT, function() { 
     log.info(startMessage); 
    }); 
    }) 
    .catch(e => log.error(e)); 
} 

const ramlErrorChecker = (err, req, res, next) => { 
    if (err) { 
    log.error("RAML validation failed. Reason: " + err); 
    res.status(400); 
    return res.json(buildResponseJSON(400)); 
    } 
    return next(); 
} 

const customNotFoundHandler = (req, res, next) => { 
    // Check for existence of the method handler. 
    if (req.resourcePath) { 
    return next() 
    } 
    res.status(404); 
    return res.json({"message": "The path is not found"}); 
} 

중요한 부분은 맞춤 설정에 도움이되는 ramlConfig입니다. "disableErrorInterception"을 true로 설정함으로써, 우리는 RAML이 사용되고 있다는 사실을 숨기고 표준화에있어 훨씬 더 나은 에러 핸들링을 인계받습니다. "notFoundHandler"를 false로 설정하면 선언되지 않은 경로는 임의 html 대신 정상적으로 거부됩니다.