mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-07-30 23:22:01 +08:00
fix: Backend crashes when invalid url is used
Improve error handling for flow info API
This commit is contained in:
parent
ffc7c07469
commit
9653b09844
6
backend/dist/cron-sync-artifacts.min.js
vendored
6
backend/dist/cron-sync-artifacts.min.js
vendored
File diff suppressed because one or more lines are too long
6
backend/dist/sub-store-parser.loon.min.js
vendored
6
backend/dist/sub-store-parser.loon.min.js
vendored
File diff suppressed because one or more lines are too long
@ -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": {
|
||||
|
27
backend/src/restful/errors/index.js
Normal file
27
backend/src/restful/errors/index.js
Normal 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';
|
||||
}
|
||||
}
|
18
backend/src/restful/response.js
Normal file
18
backend/src/restful/response.js
Normal 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,
|
||||
},
|
||||
});
|
||||
}
|
@ -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.`,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
6
backend/sub-store.min.js
vendored
6
backend/sub-store.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user