mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-09-24 23:12:34 +08:00
* chore(deps-dev): bump eslint-plugin-unicorn from 64.0.0 to 65.0.0 Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 64.0.0 to 65.0.0. - [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases) - [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v64.0.0...v65.0.0) --- updated-dependencies: - dependency-name: eslint-plugin-unicorn dependency-version: 65.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix: no-array-from-fill * fix: unicorn-js/no-duplicate-set-values * fix: no-this-outside-of-class * fix: no-unnecessary-nested-ternary * fix: prefer-array-last-methods * fix: prefer-queue-microtask * fix: prefer-split-limit * fix: no-array-from-fill * fix: no-unused-array-method-return * fix: prefer-single-call * fix: prefer-includes-over-repeated-comparisons * fix: consistent-compound-words * fix: prefer-includes-over-repeated-comparisons * chore: add eslint-plugin-unicorn v65 recommended preset * fix: correct duration parsing logic in parseDuration function * fix: update oxlint-disable --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tony <TonyRL@users.noreply.github.com>
90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
import Honeybadger from '@honeybadger-io/js';
|
|
import * as Sentry from '@sentry/node';
|
|
import type { ErrorHandler, NotFoundHandler } from 'hono';
|
|
import { routePath } from 'hono/route';
|
|
|
|
import { config } from '@/config';
|
|
import { getDebugInfo, setDebugInfo } from '@/utils/debug-info';
|
|
import logger from '@/utils/logger';
|
|
import { requestMetric } from '@/utils/otel';
|
|
import Error from '@/views/error';
|
|
|
|
import NotFoundError from './types/not-found';
|
|
|
|
export const errorHandler: ErrorHandler = (error, ctx) => {
|
|
const requestPath = ctx.req.path;
|
|
const matchedRoute = routePath(ctx);
|
|
const hasMatchedRoute = matchedRoute !== '/*';
|
|
|
|
const debug = getDebugInfo();
|
|
try {
|
|
if (ctx.res.headers.get('RSSHub-Cache-Status')) {
|
|
debug.hitCache++;
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
debug.error++;
|
|
|
|
if (!debug.errorPaths[requestPath]) {
|
|
debug.errorPaths[requestPath] = 0;
|
|
}
|
|
debug.errorPaths[requestPath]++;
|
|
|
|
if (!debug.errorRoutes[matchedRoute] && hasMatchedRoute) {
|
|
debug.errorRoutes[matchedRoute] = 0;
|
|
}
|
|
hasMatchedRoute && debug.errorRoutes[matchedRoute]++;
|
|
setDebugInfo(debug);
|
|
|
|
if (config.honeybadger.apiKey) {
|
|
Honeybadger.notify(error, {
|
|
context: { name: requestPath.split('/', 2)[1] },
|
|
});
|
|
}
|
|
|
|
if (config.sentry.dsn) {
|
|
Sentry.withScope((scope) => {
|
|
scope.setTag('name', requestPath.split('/', 2)[1]);
|
|
Sentry.captureException(error);
|
|
});
|
|
}
|
|
|
|
let errorMessage = (process.env.NODE_ENV || process.env.VERCEL_ENV) === 'production' ? error.message : error.stack || error.message;
|
|
switch (error.constructor.name) {
|
|
case 'HTTPError':
|
|
case 'RequestError':
|
|
case 'FetchError':
|
|
ctx.status(503);
|
|
break;
|
|
case 'RequestInProgressError':
|
|
ctx.header('Cache-Control', `public, max-age=${config.requestTimeout / 1000}`);
|
|
ctx.status(503);
|
|
break;
|
|
case 'RejectError':
|
|
ctx.status(403);
|
|
break;
|
|
case 'NotFoundError':
|
|
ctx.status(404);
|
|
errorMessage += 'The route does not exist or has been deleted.';
|
|
break;
|
|
default:
|
|
ctx.status(503);
|
|
break;
|
|
}
|
|
const message = `${error.name}: ${errorMessage}`;
|
|
|
|
logger.error(`Error in ${requestPath}: ${message}`);
|
|
requestMetric.error({ path: matchedRoute, method: ctx.req.method, status: ctx.res.status });
|
|
|
|
return config.isPackage || ctx.req.query('format') === 'json'
|
|
? ctx.json({
|
|
error: {
|
|
message: error.message ?? error,
|
|
},
|
|
})
|
|
: ctx.html(<Error requestPath={requestPath} message={message} errorRoute={hasMatchedRoute ? matchedRoute : requestPath} nodeVersion={process.version} />);
|
|
};
|
|
|
|
export const notFoundHandler: NotFoundHandler = (ctx) => errorHandler(new NotFoundError(), ctx);
|