Add a timeout to mongoldb connections (#15258)

* Add option to set a socket timeout for mongodb requests

* Handle mongodb timeouts better

* add default to config
This commit is contained in:
Phillip Thelen 2024-08-01 17:28:54 +02:00 committed by GitHub
parent 7f6ae8ffbf
commit 15f104ddd0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 0 deletions

View file

@ -37,6 +37,7 @@
"NODE_DB_URI": "mongodb://localhost:27017/habitica-dev?replicaSet=rs",
"TEST_DB_URI": "mongodb://localhost:27017/habitica-test?replicaSet=rs",
"MONGODB_POOL_SIZE": "10",
"MONGODB_SOCKET_TIMEOUT": "20000",
"NODE_ENV": "development",
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
"PAYPAL_BILLING_PLANS_basic_12mo": "basic_12mo",

View file

@ -60,6 +60,14 @@ export class TooManyRequests extends CustomError {
}
}
export class RequestTimeout extends CustomError {
constructor (customMessage) {
super();
this.name = this.constructor.name;
this.httpCode = 408;
this.message = customMessage || 'The request timed out.';
}
}
export class NotImplementedError extends CustomError {
constructor (str) {
super();

View file

@ -67,6 +67,19 @@ export const { Forbidden } = common.errors;
*/
export const { TooManyRequests } = common.errors;
/**
* @apiDefine RequestTimeout
* @apiError RequestTimeout The request took too long to complete.
*
* @apiErrorExample Error-Response:
* HTTP/1.1 408 RequestTimeout
* {
* "error": "RequestTimeout",
* "message": "Access forbidden."
* }
*/
export const { RequestTimeout } = common.errors;
/**
* @apiDefine NotificationNotFound
* @apiError NotificationNotFound The notification was not found.

View file

@ -9,12 +9,14 @@ import {
const IS_PROD = nconf.get('IS_PROD');
const MAINTENANCE_MODE = nconf.get('MAINTENANCE_MODE');
const POOL_SIZE = nconf.get('MONGODB_POOL_SIZE');
const SOCKET_TIMEOUT = nconf.get('MONGODB_SOCKET_TIMEOUT');
// Do not connect to MongoDB when in maintenance mode
if (MAINTENANCE_MODE !== 'true') {
const mongooseOptions = getDefaultConnectionOptions();
if (POOL_SIZE) mongooseOptions.maxPoolSize = Number(POOL_SIZE);
if (SOCKET_TIMEOUT) mongooseOptions.socketTimeoutMS = Number(SOCKET_TIMEOUT);
const DB_URI = nconf.get('IS_TEST') ? nconf.get('TEST_DB_URI') : nconf.get('NODE_DB_URI');
const connectionUrl = IS_PROD ? DB_URI : getDevelopmentConnectionUrl(DB_URI);

View file

@ -9,6 +9,7 @@ import {
CustomError,
BadRequest,
InternalServerError,
RequestTimeout,
} from '../libs/errors';
export default function errorHandler (err, req, res, next) { // eslint-disable-line no-unused-vars
@ -46,6 +47,10 @@ export default function errorHandler (err, req, res, next) { // eslint-disable-l
}));
}
if (err.name === 'MongoNetworkTimeoutError') {
responseErr = new RequestTimeout();
}
// Handle Stripe Card errors errors (can be safely shown to the users)
// https://stripe.com/docs/api/node#errors
if (err.type === 'StripeCardError') {