UNPKG

qerrors

Version:

Intelligent error handling middleware with AI-powered analysis, environment validation, caching, and production-ready logging. Provides OpenAI-based error suggestions, queue management, retry mechanisms, and comprehensive configuration options for Node.js

73 lines (66 loc) 3.38 kB
const test = require('node:test'); //node test runner const assert = require('node:assert/strict'); //strict assertions const qtests = require('qtests'); //helper for stubbing function withOpenAIToken(token) { //temporarily modify OPENAI_API_KEY const orig = process.env.OPENAI_API_KEY; //remember current token if (token === undefined) { delete process.env.OPENAI_API_KEY; } else { process.env.OPENAI_API_KEY = token; } return () => { if (orig === undefined) { delete process.env.OPENAI_API_KEY; } else { process.env.OPENAI_API_KEY = orig; } }; } function reloadQerrors() { //load qerrors fresh with current env delete require.cache[require.resolve('../lib/qerrors')]; return require('../lib/qerrors'); } test('clearAdviceCache empties cache', async () => { const restoreToken = withOpenAIToken('cache-token'); //set token for analysis const origLimit = process.env.QERRORS_CACHE_LIMIT; //save env limit process.env.QERRORS_CACHE_LIMIT = '2'; //ensure caching enabled const qerrors = reloadQerrors(); //reload module // Mock the AI model manager const { getAIModelManager } = require('../lib/aiModelManager'); const aiManager = getAIModelManager(); const originalAnalyzeError = aiManager.analyzeError; let callCount = 0; aiManager.analyzeError = async () => { callCount++; return { info: callCount === 1 ? 'one' : 'two' }; }; try { const err = new Error('boom'); err.stack = 'stack'; err.uniqueErrorName = 'CACHECLR'; const first = await qerrors.analyzeError(err, 'ctx'); assert.equal(first.info, 'one'); //initial call fetches advice await qerrors.analyzeError(err, 'ctx'); assert.equal(callCount, 1); //should use cache (no second call) qerrors.clearAdviceCache(); //reset cache const afterClear = await qerrors.analyzeError(err, 'ctx'); assert.equal(afterClear.info, 'two'); //new analysis after cache clear assert.equal(callCount, 2); //verify second call was made } finally { if (origLimit === undefined) { delete process.env.QERRORS_CACHE_LIMIT; } else { process.env.QERRORS_CACHE_LIMIT = origLimit; } aiManager.analyzeError = originalAnalyzeError; //restore AI manager restoreToken(); reloadQerrors(); } }); test('cache limit above threshold clamps and warns', async () => { const orig = process.env.QERRORS_CACHE_LIMIT; //backup current env process.env.QERRORS_CACHE_LIMIT = '5000'; //set exaggerated limit const loggerPromise = require('../lib/logger'); //logger promise for stub const log = await loggerPromise; //wait for logger instance let warned = false; //track call state const restoreWarn = qtests.stubMethod(log, 'warn', () => { warned = true; }); let limit; //will capture clamped limit try { const qerrors = reloadQerrors(); //reload module with large limit await new Promise(r => setImmediate(r)); //allow async warn callback limit = qerrors.getAdviceCacheLimit(); //fetch clamped limit value } finally { restoreWarn(); //restore logger warn if (orig === undefined) { delete process.env.QERRORS_CACHE_LIMIT; } else { process.env.QERRORS_CACHE_LIMIT = orig; } delete require.cache[require.resolve('../lib/qerrors')]; //reset state require('../lib/qerrors'); //reload defaults } assert.equal(limit, 1000); //expect clamp to safe threshold assert.equal(warned, true); //warning should fire });