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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "sub-store",
"version": "2.2.1",
"version": "2.2.2",
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
"main": "src/main.js",
"scripts": {

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.`,
),
);
}
}

File diff suppressed because one or more lines are too long