Files
RSSHub/lib/middleware/onerror.js
T
Tony 6d901cb7dc style(eslint): add eslint-unicorn (#14257)
* style: add eslint-unicorn

* style: fix unicorn/no-useless-spread

* style: fix unicorn/no-useless-promise-resolve-reject

* style: fix unicorn/no-for-loop

* fix: codeql bad HTML filtering regexp

* fix: codeql incomplete replace

* fix: unicorn/no-abusive-eslint-disable

* style: fix unicorn/no-new-array

* style: fix unicorn/no-typeof-undefined

* style: fix unicorn/no-zero-fractions

* style: fix unicorn/no-empty-file

* style: fix unicorn/prefer-date-now

* revert: auto fix unicorn/prefer-switch on lib/v2/kuaidi100/utils.js

* style: fix unicorn/prefer-array-find

* style: fix unicorn/prefer-array-flat

* style: fix unicorn/prefer-array-flat-map

* style: fix unicorn/prefer-at

* style: fix unicorn/prefer-string-starts-ends-with

* style: fix unicorn/prefer-includes

* fix: codeql URL substring sanitization

* style: fix unicorn/prefer-optional-catch-binding

* style: fix unicorn/catch-error-name

* style: fix unicorn/escape-case

* style: fix unicorn/prefer-native-coercion-functions

* style: fix unicorn/prefer-regexp-test

* style: fix unicorn/require-array-join-separator

* style: fix unicorn/prefer-math-trunc

* style: fix unicorn/prefer-negative-index

* style: fix unicorn/prefer-dom-node-dataset

* style: fix unicorn/prefer-dom-node-text-content

* style: fix unicorn/prefer-query-selector

* style: fix unicorn/no-array-for-each

* style: fix unicorn/no-negated-condition

* style: fix unicorn/prefer-add-event-listener

* style: fix unicorn/import-style

* style: fix prefer-regex-literals

* style: disable unicorn/no-useless-switch-case

* style: disable unicorn/text-encoding-identifier-case

* style: fix unicorn/prefer-set-has

* style: fix unicorn/prefer-spread

* revert: auto fix on lib/routes/universities/ynnu/edu/base64.js

* style: fix unicorn/no-useless-undefined

* style: fix unicorn/no-array-push-push

* style: fix unicorn/no-useless-undefined again

* style: fix unicorn/no-lonely-if

* style: fix unicorn/prefer-reflect-apply

* style: fix unicorn/switch-case-braces

* style: fix unicorn/prefer-switch

* style: fix unicorn/prefer-array-some

* fix: deepscan UNUSED_VAR_ASSIGN

* style: fix unicorn/prefer-ternary

* fix: follow-up of unicorn/prefer-ternary

* revert: auto fix of unicorn/prefer-string-slice for substring()

* style: disable unicorn/prefer-string-slice

fix: auto fix slice over deprecated substr

* style: fix unicorn/throw-new-error

* style: fix unicorn/filename-case

* test: fix dateParser renaming

* style: fix unicorn/better-regex

* style: fix unicorn/prefer-string-replace-all

* fix(deps): add sanitize-html

* style: fix no-prototype-builtins

* style: fix unicorn/consistent-destructuring

* style: fix unicorn/consistent-function-scoping

* style: fix unicorn/prefer-regexp-test

* style: fix unicorn/prefer-logical-operator-over-ternary

* style: fix unicorn/no-array-callback-reference

* style: add prefer-object-has-own

* style: warn unicorn/no-empty-file

* style: fix unicorn/prefer-number-properties

* style: fix no-useless-undefined again

* style: fix unicorn/numeric-separators-style

* style: disable unicorn/no-array-callback-reference

false postive with cheerio
2024-01-18 20:43:40 +08:00

120 lines
4.4 KiB
JavaScript

const logger = require('@/utils/logger');
const config = require('@/config').value;
const art = require('art-template');
const path = require('path');
const { RequestInProgressError } = require('@/errors');
let Sentry;
let gitHash;
if (config.sentry.dsn) {
Sentry = Sentry || require('@sentry/node');
Sentry.init({
dsn: config.sentry.dsn,
});
Sentry.getCurrentScope().setTag('node_name', config.nodeName);
logger.info('Sentry inited.');
}
try {
gitHash = require('git-rev-sync').short();
} catch {
gitHash = (process.env.HEROKU_SLUG_COMMIT && process.env.HEROKU_SLUG_COMMIT.slice(0, 7)) || (process.env.VERCEL_GIT_COMMIT_SHA && process.env.VERCEL_GIT_COMMIT_SHA.slice(0, 7)) || 'unknown';
}
module.exports = async (ctx, next) => {
try {
const time = Date.now();
await next();
if (config.sentry.dsn && Date.now() - time >= config.sentry.routeTimeout) {
Sentry.withScope((scope) => {
scope.setTag('route', ctx._matchedRoute);
scope.setTag('name', ctx.request.path.split('/')[1]);
scope.addEventProcessor((event) => Sentry.Handlers.parseRequest(event, ctx.request));
Sentry.captureException(new Error('Route Timeout'));
});
}
} catch (error) {
if (error instanceof Error && !error.stack.split('\n')[1].includes('lib/middleware/parameter.js')) {
// Append v2 route path if a route throws an error
// since koa-mount will remove the mount path from ctx.request.path
// https://github.com/koajs/mount/issues/62
ctx.request.path = (ctx.mountPath ?? '') + ctx.request.path;
ctx._matchedRoute = ctx._matchedRoute ? (ctx.mountPath ?? '') + ctx._matchedRoute : ctx._matchedRoute;
}
let message = error;
if (error.name && (error.name === 'HTTPError' || error.name === 'RequestError')) {
message = `${error.message}: target website might be blocking our access, you can <a href="https://docs.rsshub.app/install/">host your own RSSHub instance</a> for a better usability.`;
} else if (error instanceof Error) {
message = process.env.NODE_ENV === 'production' ? error.message : error.stack;
}
logger.error(`Error in ${ctx.request.path}: ${message}`);
if (config.isPackage) {
ctx.body = {
error: {
message: error.message ?? error,
},
};
} else {
ctx.set({
'Content-Type': 'text/html; charset=UTF-8',
});
if (error instanceof RequestInProgressError) {
ctx.status = 503;
message = error.message;
ctx.set('Cache-Control', `public, max-age=${config.cache.requestTimeout}`);
} else if (ctx.status === 403) {
message = error.message;
} else {
ctx.status = 404;
}
const requestPath = ctx.request.path;
ctx.body = art(path.resolve(__dirname, '../views/error.art'), {
requestPath,
message,
errorPath: ctx.path,
nodeVersion: process.version,
gitHash,
});
}
if (!ctx.debug.errorPaths[ctx.request.path]) {
ctx.debug.errorPaths[ctx.request.path] = 0;
}
ctx.debug.errorPaths[ctx.request.path]++;
if (!ctx.debug.errorRoutes[ctx._matchedRoute]) {
ctx._matchedRoute && (ctx.debug.errorRoutes[ctx._matchedRoute] = 0);
}
ctx._matchedRoute && ctx.debug.errorRoutes[ctx._matchedRoute]++;
if (!ctx.state.debuged) {
if (!ctx.debug.routes[ctx._matchedRoute]) {
ctx._matchedRoute && (ctx.debug.routes[ctx._matchedRoute] = 0);
}
ctx._matchedRoute && ctx.debug.routes[ctx._matchedRoute]++;
if (ctx.response.get('X-Koa-Redis-Cache') || ctx.response.get('X-Koa-Memory-Cache')) {
ctx.debug.hitCache++;
}
}
if (config.sentry.dsn) {
Sentry.withScope((scope) => {
scope.setTag('route', ctx._matchedRoute);
scope.setTag('name', ctx.request.path.split('/')[1]);
scope.addEventProcessor((event) => Sentry.Handlers.parseRequest(event, ctx.request));
Sentry.captureException(error);
});
}
}
};