Fix silently unhandled database exceptions

This commit is contained in:
Mononaut 2023-11-14 05:00:05 +00:00
parent cbe1ec4e72
commit 1ae34e069c
No known key found for this signature in database
GPG Key ID: A3F058E41374C04E
4 changed files with 36 additions and 10 deletions

View File

@ -761,8 +761,13 @@ class Blocks {
this.updateTimerProgress(timer, `saved ${this.currentBlockHeight} to database`); this.updateTimerProgress(timer, `saved ${this.currentBlockHeight} to database`);
if (!fastForwarded) { if (!fastForwarded) {
const lastestPriceId = await PricesRepository.$getLatestPriceId(); let lastestPriceId;
this.updateTimerProgress(timer, `got latest price id ${this.currentBlockHeight}`); try {
lastestPriceId = await PricesRepository.$getLatestPriceId();
this.updateTimerProgress(timer, `got latest price id ${this.currentBlockHeight}`);
} catch (e) {
logger.debug('failed to fetch latest price id from db: ' + (e instanceof Error ? e.message : e));
}
if (priceUpdater.historyInserted === true && lastestPriceId !== null) { if (priceUpdater.historyInserted === true && lastestPriceId !== null) {
await blocksRepository.$saveBlockPrices([{ await blocksRepository.$saveBlockPrices([{
height: blockExtended.height, height: blockExtended.height,

View File

@ -55,14 +55,20 @@ import { execSync } from 'child_process';
}).then(result => { }).then(result => {
resolve(result); resolve(result);
}).catch(error => { }).catch(error => {
logger.debug(`database query "${query.slice(0, 100)}" failed!`);
reject(error); reject(error);
}).finally(() => { }).finally(() => {
clearTimeout(timer); clearTimeout(timer);
}); });
}); });
} else { } else {
const pool = await this.getPool(); try {
return pool.query(query, params); const pool = await this.getPool();
return pool.query(query, params);
} catch (e) {
logger.debug(`database query "${query.slice(0, 100)}" failed!`);
throw e;
}
} }
} }

View File

@ -92,9 +92,15 @@ class Server {
logger.notice(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`); logger.notice(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`);
// Register cleanup listeners for exit events // Register cleanup listeners for exit events
['exit', 'SIGHUP', 'SIGINT', 'SIGTERM', 'SIGUSR1', 'SIGUSR2', 'uncaughtException', 'unhandledRejection'].forEach(event => { ['exit', 'SIGHUP', 'SIGINT', 'SIGTERM', 'SIGUSR1', 'SIGUSR2'].forEach(event => {
process.on(event, () => { this.onExit(event); }); process.on(event, () => { this.onExit(event); });
}); });
process.on('uncaughtException', (error) => {
this.onUnhandledException('uncaughtException', error);
});
process.on('unhandledRejection', (reason, promise) => {
this.onUnhandledException('unhandledRejection', reason);
});
if (config.MEMPOOL.BACKEND === 'esplora') { if (config.MEMPOOL.BACKEND === 'esplora') {
bitcoinApi.startHealthChecks(); bitcoinApi.startHealthChecks();
@ -314,14 +320,18 @@ class Server {
} }
} }
onExit(exitEvent): void { onExit(exitEvent, code = 0): void {
logger.debug(`onExit for signal: ${exitEvent}`);
if (config.DATABASE.ENABLED) { if (config.DATABASE.ENABLED) {
DB.releasePidLock(); DB.releasePidLock();
} }
process.exit(0); process.exit(code);
}
onUnhandledException(type, error): void {
console.error(`${type}:`, error);
this.onExit(type, 1);
} }
} }
((): Server => new Server())(); ((): Server => new Server())();

View File

@ -76,7 +76,12 @@ class Indexer {
if (task === 'blocksPrices' && !this.tasksRunning.includes(task) && !['testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) { if (task === 'blocksPrices' && !this.tasksRunning.includes(task) && !['testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) {
this.tasksRunning.push(task); this.tasksRunning.push(task);
const lastestPriceId = await PricesRepository.$getLatestPriceId(); let lastestPriceId;
try {
lastestPriceId = await PricesRepository.$getLatestPriceId();
} catch (e) {
logger.debug('failed to fetch latest price id from db: ' + (e instanceof Error ? e.message : e));
}
if (priceUpdater.historyInserted === false || lastestPriceId === null) { if (priceUpdater.historyInserted === false || lastestPriceId === null) {
logger.debug(`Blocks prices indexer is waiting for the price updater to complete`, logger.tags.mining); logger.debug(`Blocks prices indexer is waiting for the price updater to complete`, logger.tags.mining);
setTimeout(() => { setTimeout(() => {