Browse Source

Common mechanism for handling errors #474 (#475)

* handling middleware

* rm try/catch in routers
pull/1/head
Alexey Velikiy 6 years ago committed by GitHub
parent
commit
29b1977a39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      server/src/index.ts
  2. 282
      server/src/routes/analytic_units_router.ts
  3. 74
      server/src/routes/panel_router.ts
  4. 76
      server/src/routes/segments_router.ts
  5. 64
      server/src/routes/threshold_router.ts

12
server/src/index.ts

@ -33,6 +33,18 @@ app.use(async function(ctx, next) {
ctx.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); ctx.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
await next(); await next();
}); });
app.use(async function(ctx, next) {
try {
await next();
} catch (e) {
console.error(e);
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `${ctx.method} ${ctx.url} error: ${e.message}`
};
}
});
var rootRouter = new Router(); var rootRouter = new Router();

282
server/src/routes/analytic_units_router.ts

@ -7,85 +7,55 @@ import * as Router from 'koa-router';
async function getStatus(ctx: Router.IRouterContext) { async function getStatus(ctx: Router.IRouterContext) {
try { let analyticUnitId = ctx.request.query.id;
let analyticUnitId = ctx.request.query.id; if(analyticUnitId === undefined) {
if(analyticUnitId === undefined) { throw new Error('Cannot get status of undefined id');
throw new Error('Cannot get status of undefined id'); }
}
let analyticUnit = await AnalyticUnit.findById(analyticUnitId);
let analyticUnit = await AnalyticUnit.findById(analyticUnitId); if(analyticUnit === null) {
if(analyticUnit === null) { throw new Error(`Cannot find analytic unit with id ${analyticUnitId}`);
throw new Error(`Cannot find analytic unit with id ${analyticUnitId}`); }
}
ctx.response.body = {
ctx.response.body = { status: analyticUnit.status
status: analyticUnit.status };
};
if(analyticUnit.status === AnalyticUnit.AnalyticUnitStatus.FAILED) {
if(analyticUnit.status === AnalyticUnit.AnalyticUnitStatus.FAILED) { ctx.response.body.errorMessage = analyticUnit.error;
ctx.response.body.errorMessage = analyticUnit.error;
}
} catch(e) {
console.error(e);
ctx.response.status = 404;
ctx.response.body = {
code: 404,
message: `GET /analyticUnits/status error: ${e.message}`
};
} }
} }
async function getUnit(ctx: Router.IRouterContext) { async function getUnit(ctx: Router.IRouterContext) {
try { let analyticUnitId = ctx.request.query.id;
let analyticUnitId = ctx.request.query.id; if(analyticUnitId === undefined) {
if(analyticUnitId === undefined) { throw new Error('No id param in query');
throw new Error('No id param in query'); }
}
let analyticUnit = await AnalyticUnit.findById(analyticUnitId);
let analyticUnit = await AnalyticUnit.findById(analyticUnitId); if(analyticUnit === null) {
if(analyticUnit === null) { throw new Error(`Cannot find analytic unit with id ${analyticUnitId}`);
throw new Error(`Cannot find analytic unit with id ${analyticUnitId}`);
}
ctx.response.body = {
name: analyticUnit.name,
metric: analyticUnit.metric,
status: analyticUnit.status
};
} catch(e) {
console.error(e);
ctx.response.status = 404;
ctx.response.body = {
code: 404,
message: `GET /analyticUnits error: ${e.message}`
};
} }
ctx.response.body = {
name: analyticUnit.name,
metric: analyticUnit.metric,
status: analyticUnit.status
};
} }
async function getUnits(ctx: Router.IRouterContext) { async function getUnits(ctx: Router.IRouterContext) {
try { const panelUrl = ctx.request.query.panelUrl;
const panelUrl = ctx.request.query.panelUrl; if(panelUrl === undefined) {
if(panelUrl === undefined) { throw new Error('Cannot get alerts of undefined panelUrl');
throw new Error('Cannot get alerts of undefined panelUrl'); }
}
let analyticUnits = await AnalyticUnit.findMany({ panelUrl });
let analyticUnits = await AnalyticUnit.findMany({ panelUrl }); if(analyticUnits === null) {
if(analyticUnits === null) { analyticUnits = [];
analyticUnits = [];
}
ctx.response.body = {
analyticUnits
};
} catch(e) {
console.error(e);
ctx.response.status = 404;
ctx.response.body = {
code: 404,
message: `GET /analyticUnits/units error: ${e.message}`
};
} }
ctx.response.body = { analyticUnits };
} }
function getTypes(ctx: Router.IRouterContext) { function getTypes(ctx: Router.IRouterContext) {
@ -93,140 +63,88 @@ function getTypes(ctx: Router.IRouterContext) {
} }
async function createUnit(ctx: Router.IRouterContext) { async function createUnit(ctx: Router.IRouterContext) {
try { let id = await createAnalyticUnitFromObject(ctx.request.body);
let id = await createAnalyticUnitFromObject(ctx.request.body); ctx.response.body = { id };
ctx.response.body = { id };
} catch(e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `POST /analyticUnits error: ${e.message}`
};
}
} }
async function updateUnit(ctx: Router.IRouterContext) { async function updateUnit(ctx: Router.IRouterContext) {
try { const unit = ctx.request.body as AnalyticUnit.AnalyticUnit;
const unit = ctx.request.body as AnalyticUnit.AnalyticUnit; if(unit.id === undefined) {
if(unit.id === undefined) { throw new Error('Cannot update undefined id');
throw new Error('Cannot update undefined id');
}
// TODO: we can't allow to update everything
AnalyticUnit.update(unit.id, unit);
ctx.response.body = {
code: 200,
message: 'Success'
};
} catch (e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `PATCH /analyticUnits error: ${e.message}`
};
} }
// TODO: we can't allow to update everything
AnalyticUnit.update(unit.id, unit);
ctx.response.body = {
code: 200,
message: 'Success'
};
} }
async function updateMetric(ctx: Router.IRouterContext) { async function updateMetric(ctx: Router.IRouterContext) {
try { const { analyticUnitId, metric, datasource } = ctx.request.body as {
const { analyticUnitId, metric, datasource } = ctx.request.body as { analyticUnitId: AnalyticUnit.AnalyticUnitId, metric: any, datasource: any
analyticUnitId: AnalyticUnit.AnalyticUnitId, metric: any, datasource: any };
}; if(analyticUnitId === undefined) {
if(analyticUnitId === undefined) { throw new Error('Cannot update undefined id');
throw new Error('Cannot update undefined id'); }
} if(metric === undefined) {
if(metric === undefined) { throw new Error('Cannot set undefined metric');
throw new Error('Cannot set undefined metric'); }
} if(datasource === undefined) {
if(datasource === undefined) { throw new Error('Cannot set undefined datasource');
throw new Error('Cannot set undefined datasource');
}
await AnalyticsController.setMetric(analyticUnitId, metric, datasource);
ctx.response.body = {
code: 200,
message: 'Success'
};
} catch (e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `PATCH /analyticUnits/metric error: ${e.message}`
};
} }
await AnalyticsController.setMetric(analyticUnitId, metric, datasource);
ctx.response.body = {
code: 200,
message: 'Success'
};
} }
async function updateAlert(ctx: Router.IRouterContext) { async function updateAlert(ctx: Router.IRouterContext) {
try { const { analyticUnitId, alert } = ctx.request.body as {
const { analyticUnitId, alert } = ctx.request.body as { analyticUnitId: AnalyticUnit.AnalyticUnitId, alert: boolean
analyticUnitId: AnalyticUnit.AnalyticUnitId, alert: boolean };
}; if(analyticUnitId === undefined) {
if(analyticUnitId === undefined) { throw new Error('Cannot update undefined id');
throw new Error('Cannot update undefined id'); }
} if(alert === undefined) {
if(alert === undefined) { throw new Error('Cannot set undefined alert status');
throw new Error('Cannot set undefined alert status');
}
await AnalyticsController.setAlert(analyticUnitId, alert);
ctx.response.body = {
code: 200,
message: 'Success'
};
} catch(e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `PATCH /analyticUnits/alert error: ${e.message}`
};
} }
await AnalyticsController.setAlert(analyticUnitId, alert);
ctx.response.body = {
code: 200,
message: 'Success'
};
} }
async function deleteUnit(ctx: Router.IRouterContext) { async function deleteUnit(ctx: Router.IRouterContext) {
try { const analyticUnitId = ctx.request.query.id;
const analyticUnitId = ctx.request.query.id; if(analyticUnitId === undefined) {
if(analyticUnitId === undefined) { throw new Error('Cannot delete undefined id');
throw new Error('Cannot delete undefined id');
}
await AnalyticsController.remove(analyticUnitId);
ctx.response.body = {
code: 200,
message: 'Success'
};
} catch(e) {
console.error(e);
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `DELETE /analyticUnits error: ${e.message}`
};
} }
await AnalyticsController.remove(analyticUnitId);
ctx.response.body = {
code: 200,
message: 'Success'
};
} }
async function runDetect(ctx: Router.IRouterContext) { async function runDetect(ctx: Router.IRouterContext) {
try { const { id: analyticUnitId } = ctx.request.body as { id: AnalyticUnit.AnalyticUnitId };
const { id: analyticUnitId } = ctx.request.body as { id: AnalyticUnit.AnalyticUnitId }; AnalyticsController.runFirstLearning(analyticUnitId);
ctx.response.body = {
AnalyticsController.runFirstLearning(analyticUnitId); code: 200,
message: 'Success'
ctx.response.body = { };
code: 200,
message: 'Success'
};
} catch (e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `POST /analyticUnits/detect error: ${e.message}`
};
}
} }
export var router = new Router(); export var router = new Router();
router.get('/', getUnit); router.get('/', getUnit);

74
server/src/routes/panel_router.ts

@ -5,65 +5,35 @@ import * as Router from 'koa-router';
async function getAnalyticUnits(ctx: Router.IRouterContext) { async function getAnalyticUnits(ctx: Router.IRouterContext) {
try { let panelUrl: string = ctx.request.query.panelUrl;
let panelUrl: string = ctx.request.query.panelUrl; if(panelUrl === undefined || panelUrl === '') {
if(panelUrl === undefined || panelUrl === '') { throw new Error('panelUrl is missing');
throw new Error('panelUrl is missing');
}
const analyticUnits = await Panel.findOne({ panelUrl });
ctx.response.body = { analyticUnits };
} catch(e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `GET /panel error: ${e.message}`
};
} }
const analyticUnits = await Panel.findOne({ panelUrl });
ctx.response.body = { analyticUnits };
} }
async function addAnalyticUnit(ctx: Router.IRouterContext) { async function addAnalyticUnit(ctx: Router.IRouterContext) {
try { let { panelUrl, analyticUnitId } = ctx.request.body as {
let { panelUrl, analyticUnitId } = ctx.request.body as { panelUrl: string, analyticUnitId: AnalyticUnitId
panelUrl: string, analyticUnitId: AnalyticUnitId };
}; await Panel.insertAnalyticUnit(panelUrl, analyticUnitId);
ctx.response.body = {
await Panel.insertAnalyticUnit(panelUrl, analyticUnitId); code: 200,
message: 'Success'
ctx.response.body = { };
code: 200,
message: 'Success'
};
} catch(e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `POST /panel error: ${e.message}`
};
}
} }
async function deleteAnalyticUnit(ctx: Router.IRouterContext) { async function deleteAnalyticUnit(ctx: Router.IRouterContext) {
try { let { panelUrl, analyticUnitId } = ctx.request.body as {
let { panelUrl, analyticUnitId } = ctx.request.body as { panelUrl: string, analyticUnitId: AnalyticUnitId
panelUrl: string, analyticUnitId: AnalyticUnitId };
}; // TODO: stop task when analytic unit is removed
await Panel.removeAnalyticUnit(panelUrl, analyticUnitId);
// TODO: stop task when analytic unit is removed ctx.response.body = {
await Panel.removeAnalyticUnit(panelUrl, analyticUnitId); code: 200,
message: 'Success'
ctx.response.body = { };
code: 200,
message: 'Success'
};
} catch(e) {
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `DELETE /panel error: ${e.message}`
};
}
} }
export const router = new Router(); export const router = new Router();

76
server/src/routes/segments_router.ts

@ -7,63 +7,41 @@ import * as Router from 'koa-router';
async function getSegments(ctx: Router.IRouterContext) { async function getSegments(ctx: Router.IRouterContext) {
try { let id: AnalyticUnitId = ctx.request.query.id;
let id: AnalyticUnitId = ctx.request.query.id; if(id === undefined || id === '') {
if(id === undefined || id === '') { throw new Error('analyticUnitId (id) is missing');
throw new Error('analyticUnitId (id) is missing'); }
} let query: Segment.FindManyQuery = {};
let query: Segment.FindManyQuery = {};
if(!isNaN(+ctx.request.query.lastSegmentId)) {
query.intexGT = +ctx.request.query.lastSegmentId;
}
if(!isNaN(+ctx.request.query.from)) {
query.timeFromGTE = +ctx.request.query.from;
}
if(!isNaN(+ctx.request.query.to)) {
query.timeToLTE = +ctx.request.query.to;
}
let segments = await Segment.findMany(id, query);
ctx.response.body = { segments }; if(!isNaN(+ctx.request.query.lastSegmentId)) {
} catch(e) { query.intexGT = +ctx.request.query.lastSegmentId;
console.error(e); }
ctx.response.status = 500; if(!isNaN(+ctx.request.query.from)) {
ctx.response.body = { query.timeFromGTE = +ctx.request.query.from;
code: 500,
message: `GET /segments error: ${e.message}`
};
} }
if(!isNaN(+ctx.request.query.to)) {
query.timeToLTE = +ctx.request.query.to;
}
let segments = await Segment.findMany(id, query);
ctx.response.body = { segments };
} }
async function updateSegments(ctx: Router.IRouterContext) { async function updateSegments(ctx: Router.IRouterContext) {
try { const {
addedSegments, id, removedSegments: removedIds
const { } = ctx.request.body as {
addedSegments, id, removedSegments: removedIds addedSegments: any[], id: AnalyticUnitId, removedSegments: Segment.SegmentId[]
} = ctx.request.body as { };
addedSegments: any[], id: AnalyticUnitId, removedSegments: Segment.SegmentId[]
};
const segmentsToInsert: Segment.Segment[] = addedSegments.map( const segmentsToInsert: Segment.Segment[] = addedSegments.map(
s => Segment.Segment.fromObject({ analyticUnitId: id, ...s }) s => Segment.Segment.fromObject({ analyticUnitId: id, ...s })
); );
const { addedIds } = await AnalyticsController.updateSegments( const { addedIds } = await AnalyticsController.updateSegments(
id, segmentsToInsert, removedIds id, segmentsToInsert, removedIds
); );
ctx.response.body = { addedIds }; ctx.response.body = { addedIds };
} catch(e) {
console.error(e);
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `PATCH /segments (learning) error: ${e.message}`
};
}
} }
export const router = new Router(); export const router = new Router();

64
server/src/routes/threshold_router.ts

@ -8,50 +8,34 @@ import * as _ from 'lodash';
async function getThresholds(ctx: Router.IRouterContext) { async function getThresholds(ctx: Router.IRouterContext) {
try {
const ids: AnalyticUnitId[] = ctx.request.query.ids.split(','); const ids: AnalyticUnitId[] = ctx.request.query.ids.split(',');
if(ids === undefined) { if(ids === undefined) {
throw new Error('analyticUnitIds (ids) are missing'); throw new Error('analyticUnitIds (ids) are missing');
}
const thresholds = await Promise.all(
_.map(ids, id => Threshold.findOne(id))
);
ctx.response.body = { thresholds };
} catch(e) {
console.error(e);
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `GET /threshold error: ${e.message}`
};
} }
const thresholds = await Promise.all(
_.map(ids, id => Threshold.findOne(id))
);
ctx.response.body = { thresholds };
} }
async function updateThreshold(ctx: Router.IRouterContext) { async function updateThreshold(ctx: Router.IRouterContext) {
try { const {
const { id, value, condition
id, value, condition } = ctx.request.body as {
} = ctx.request.body as { id: AnalyticUnitId, value: number, condition: Threshold.Condition
id: AnalyticUnitId, value: number, condition: Threshold.Condition };
};
await AnalyticsController.updateThreshold(id, value, condition);
await AnalyticsController.updateThreshold(id, value, condition);
ctx.response.body = {
ctx.response.body = { code: 200,
code: 200, message: 'Success'
message: 'Success' };
};
} catch(e) {
console.error(e);
ctx.response.status = 500;
ctx.response.body = {
code: 500,
message: `PATCH /threshold error: ${e.message}`
};
}
} }
export const router = new Router(); export const router = new Router();

Loading…
Cancel
Save