mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-07-31 20:01:59 +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",
|
"name": "sub-store",
|
||||||
"version": "2.2.1",
|
"version": "2.2.2",
|
||||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"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 { SUBS_KEY, COLLECTIONS_KEY } from './constants';
|
||||||
import { produceArtifact } from './artifacts';
|
import { produceArtifact } from './artifacts';
|
||||||
|
import { success, failed } from './response';
|
||||||
import $ from '@/core/app';
|
import $ from '@/core/app';
|
||||||
|
|
||||||
export default function register($app) {
|
export default function register($app) {
|
||||||
@ -80,24 +86,25 @@ async function getFlowInfo(req, res) {
|
|||||||
const sub = $.read(SUBS_KEY)[name];
|
const sub = $.read(SUBS_KEY)[name];
|
||||||
|
|
||||||
if (!sub) {
|
if (!sub) {
|
||||||
res.status(404).json({
|
failed(
|
||||||
status: 'failed',
|
res,
|
||||||
code: 'NOT_FOUND',
|
new ResourceNotFoundError(
|
||||||
});
|
'RESOURCE_NOT_FOUND',
|
||||||
|
`Subscription ${name} does not exist!`,
|
||||||
|
),
|
||||||
|
404,
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (sub.source === 'local') {
|
if (sub.source === 'local') {
|
||||||
res.status(500).json({
|
failed(res, new InternalServerError('NO_FLOW_INFO', 'N/A'));
|
||||||
status: 'failed',
|
return;
|
||||||
code: 'IS_LOCAL_SUB',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const flowHeaders = await getFlowHeaders(sub.url);
|
const flowHeaders = await getFlowHeaders(sub.url);
|
||||||
if (!flowHeaders) {
|
if (!flowHeaders) {
|
||||||
res.status(500).json({
|
failed(res, new InternalServerError('NO_FLOW_INFO', 'N/A'));
|
||||||
status: 'failed',
|
return;
|
||||||
code: 'NO_FLOW_INFO',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unit is KB
|
// unit is KB
|
||||||
@ -106,24 +113,18 @@ async function getFlowInfo(req, res) {
|
|||||||
const total = Number(flowHeaders.match(/total=(\d+)/)[1]);
|
const total = Number(flowHeaders.match(/total=(\d+)/)[1]);
|
||||||
|
|
||||||
// optional expire timestamp
|
// 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({
|
success(res, { expires, total, usage: { upload, download } });
|
||||||
status: 'success',
|
|
||||||
data: {
|
|
||||||
expires: expires ? Number(expires[1]) : undefined,
|
|
||||||
total,
|
|
||||||
usage: {
|
|
||||||
upload,
|
|
||||||
download,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
res.status(500).json({
|
failed(
|
||||||
status: 'failed',
|
res,
|
||||||
code: 'NOT_AVAILABLE',
|
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