diff --git a/src/api/middlewares/error.spec.ts b/src/api/middlewares/error.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..be9181ab3f2f90643661c91f29d940b571ed6993 --- /dev/null +++ b/src/api/middlewares/error.spec.ts @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 Centro de Computacao Cientifica e Software Livre + * Departamento de Informatica - Universidade Federal do Parana + * + * This file is part of blendb. + * + * blendb is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * blendb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with blendb. If not, see <http://www.gnu.org/licenses/>. + */ + +import * as request from "supertest"; +import { expect } from "chai"; + +import * as server from "../../main"; + +describe("API error middleware", () => { + + it("should respond 404 when a route does not exists", (done) => { + request(server) + .get("/v1/inexistent") + .expect(404) + .expect((res: any) => { + const error = "Cannot GET /v1/inexistent"; + expect(res.body).to.be.an("object"); + expect(res.body).to.have.property("error"); + expect(res.body.error).to.be.eql(error); + }) + .end(done); + }); + + it("should respond 400 for missing required parameters", (done) => { + request(server) + .get("/v1/data") + .query({metrics: "random"}) + .expect(400) + .expect((res: any) => { + const error = "Bad request: Some problems with this request were found"; + expect(res.body).to.be.an("object"); + expect(res.body).to.have.property("error"); + expect(res.body).to.have.property("requestErrors"); + expect(res.body.error).to.be.eql(error); + expect(res.body.requestErrors).to.have.length(1); + }) + .end(done); + }); +}); diff --git a/src/api/middlewares/error.ts b/src/api/middlewares/error.ts new file mode 100644 index 0000000000000000000000000000000000000000..a35bb41e8b2ca7d71c18253b8b252201e6685ac7 --- /dev/null +++ b/src/api/middlewares/error.ts @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 Centro de Computacao Cientifica e Software Livre + * Departamento de Informatica - Universidade Federal do Parana + * + * This file is part of blendb. + * + * blendb is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * blendb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with blendb. If not, see <http://www.gnu.org/licenses/>. + */ + +import * as express from "express"; + +export function ErrorMw(config: string): express.ErrorRequestHandler { + const handlers: { [key: string]: express.ErrorRequestHandler } = { + "v1": function(err, req, res, next) { + if (err.ramlNotFound) { + const splited = err.toString().split(" "); + const method = splited[1]; + const route = "/v1" + splited[2]; + res.status(404).json({ error: "Cannot " + method + " " + route }); + } + + else if (err.ramlValidation) { + res.status(400).json({ + error: "Bad request: Some problems with this request were found" + , requestErrors: err.requestErrors + }); + } + + else if (err.ramlAuthorization) { + res.status(401).json({ + error: "Unauthorized: Some problems with your authentication were found, try to authenticate again" + , requestErrors: err.authorizationErrors + }); + } + + else { + res.status(400).json({error: err.toString()}); + } + + return; + }, + + "default": function(err, req, res, next) { + next(err); + return; + } + }; + + if (handlers[config]) { + return handlers[config]; + } + + else { + return handlers.default; + } +}; diff --git a/src/main.ts b/src/main.ts index 658c9ed66295c837d8dd8aacad5b9989e1c233ac..3928f5f519b0ec9df1250ebd636d7c6e552ba7da 100755 --- a/src/main.ts +++ b/src/main.ts @@ -39,6 +39,7 @@ const config = ConfigParser.parse(configPath); // include middlewares import { EngineMw } from "./api/middlewares/engine"; import { PostgresMw } from "./api/middlewares/adapter"; +import { ErrorMw } from "./api/middlewares/error"; app.use(EngineMw(config)); app.use(PostgresMw(config.connection)); @@ -51,6 +52,8 @@ ramlParser.loadFile("specs/blendb-api-v1.raml") osprey.server(raml), router); + app.use("/v1", ErrorMw("v1")); + let port = process.env.PORT || 3000; app.listen(port);