From c7111329dca353704244fe747b8f6cf8c672ca0a Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Tue, 10 Mar 2026 04:41:30 +0100 Subject: [PATCH] Improved knex error reporting. --- .eslintrc | 2 +- src/knex.js | 22 +++++++++++++++++++++- src/tools/huge-query.js | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/tools/huge-query.js diff --git a/.eslintrc b/.eslintrc index 202d4f21..59d7a632 100755 --- a/.eslintrc +++ b/.eslintrc @@ -27,7 +27,7 @@ "require-await": "off", "no-param-reassign": ["error", { "props": true, - "ignorePropertyModificationsFor": ["state", "acc", "req"] + "ignorePropertyModificationsFor": ["state", "acc", "req", "error"] }] }, "globals": { diff --git a/src/knex.js b/src/knex.js index a815d929..3a1b4710 100755 --- a/src/knex.js +++ b/src/knex.js @@ -3,7 +3,7 @@ const config = require('config'); const knex = require('knex'); -module.exports = knex({ +const knexInstance = knex({ client: 'pg', connection: config.database.owner, pool: config.database.pool, @@ -11,3 +11,23 @@ module.exports = knex({ asyncStackTraces: process.env.NODE_ENV === 'development', // debug: process.env.NODE_ENV === 'development', }); + +knexInstance.on('query', function onQuery(query) { + const bindingCount = query.bindings?.length ?? 0; + + if (bindingCount > 10000) { + const error = new Error(`[knex] Dangerous query: ${bindingCount} bindings detected: ${query.sql?.slice(0, 200)}${query.sql?.length > 200 ? '...' : ''}`); + + Error.captureStackTrace(error, onQuery); + // console.error(error); + + throw error; // optionally hard-fail so you get a real stack trace + } +}); + +knexInstance.on('query-error', (error, query) => { + error.knexSql = `${query.sql?.slice(0, 200)}${query.sql?.length > 200 ? '...' : ''}`; + error.knexBindingCount = query.bindings?.length; +}); + +module.exports = knexInstance; diff --git a/src/tools/huge-query.js b/src/tools/huge-query.js new file mode 100644 index 00000000..7da2030b --- /dev/null +++ b/src/tools/huge-query.js @@ -0,0 +1,15 @@ +'use strict'; + +const knex = require('../knex'); + +async function init() { + const data = Array.from({ length: 100_000 }, (value, index) => ({ + id: `test_affiliate_${index}`, + })); + + await knex('affiliates').insert(data); + + console.log('Done!'); +} + +init();