fix: Backend crashes when invalid url is used

Improve error handling for flow info API
This commit is contained in:
Peng-YM
2022-06-29 14:07:22 +08:00
parent ffc7c07469
commit 9653b09844
7 changed files with 84 additions and 38 deletions

View File

@@ -0,0 +1,27 @@
class BaseError {
constructor(code, message, details) {
this.message = message;
this.details = details;
}
}
export class InternalServerError extends BaseError {
constructor(code, message, details) {
super(code, message, details);
this.type = 'InternalServerError';
}
}
export class ResourceNotFoundError extends BaseError {
constructor(code, message, details) {
super(code, message, details);
this.type = 'ResourceNotFoundError';
}
}
export class NetworkError extends BaseError {
constructor(code, message, details) {
super(code, message, details);
this.type = 'NetworkError';
}
}

View File

@@ -0,0 +1,18 @@
export function success(resp, data, statusCode) {
resp.status(statusCode || 200).json({
status: 'success',
data,
});
}
export function failed(resp, error, statusCode) {
resp.status(statusCode || 500).json({
status: 'failed',
error: {
code: error.code,
type: error.type,
message: error.message,
details: error.details,
},
});
}

View File

@@ -1,5 +1,11 @@
import {
NetworkError,
InternalServerError,
ResourceNotFoundError,
} from './errors';
import { SUBS_KEY, COLLECTIONS_KEY } from './constants';
import { produceArtifact } from './artifacts';
import { success, failed } from './response';
import $ from '@/core/app';
export default function register($app) {
@@ -80,24 +86,25 @@ async function getFlowInfo(req, res) {
const sub = $.read(SUBS_KEY)[name];
if (!sub) {
res.status(404).json({
status: 'failed',
code: 'NOT_FOUND',
});
failed(
res,
new ResourceNotFoundError(
'RESOURCE_NOT_FOUND',
`Subscription ${name} does not exist!`,
),
404,
);
return;
}
if (sub.source === 'local') {
res.status(500).json({
status: 'failed',
code: 'IS_LOCAL_SUB',
});
failed(res, new InternalServerError('NO_FLOW_INFO', 'N/A'));
return;
}
try {
const flowHeaders = await getFlowHeaders(sub.url);
if (!flowHeaders) {
res.status(500).json({
status: 'failed',
code: 'NO_FLOW_INFO',
});
failed(res, new InternalServerError('NO_FLOW_INFO', 'N/A'));
return;
}
// unit is KB
@@ -106,24 +113,18 @@ async function getFlowInfo(req, res) {
const total = Number(flowHeaders.match(/total=(\d+)/)[1]);
// optional expire timestamp
const expires = flowHeaders.match(/expire=(\d+)/);
const match = flowHeaders.match(/expire=(\d+)/);
const expires = match ? Number(match[1]) : undefined;
res.status(200).json({
status: 'success',
data: {
expires: expires ? Number(expires[1]) : undefined,
total,
usage: {
upload,
download,
},
},
});
success(res, { expires, total, usage: { upload, download } });
} catch (err) {
res.status(500).json({
status: 'failed',
code: 'NOT_AVAILABLE',
});
failed(
res,
new NetworkError(
`URL_NOT_ACCESSIBLE`,
`The URL for subscription ${name} is inaccessible.`,
),
);
}
}