{"record":{"id":"71a5e4d2f5351b6e","repo":"winstonjs/winston","slug":"logger-is-required-for-profiling","errorCode":null,"errorMessage":"Logger is required for profiling","messagePattern":"Logger is required for profiling","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/winston/profiler.js","lineNumber":25,"sourceCode":"\n'use strict';\n/**\n * TODO: add class description.\n * @type {Profiler}\n * @private\n */\nclass Profiler {\n  /**\n   * Constructor function for the Profiler instance used by\n   * `Logger.prototype.startTimer`. When done is called the timer will finish\n   * and log the duration.\n   * @param {!Logger} logger - TODO: add param description.\n   * @private\n   */\n  constructor(logger) {\n    const Logger = require('./logger');\n    if (typeof logger !== 'object' || Array.isArray(logger) || !(logger instanceof Logger)) {\n      throw new Error('Logger is required for profiling');\n    } else {\n      this.logger = logger;\n      this.start = Date.now();\n    }\n  }\n\n  /**\n   * Ends the current timer (i.e. Profiler) instance and logs the `msg` along\n   * with the duration since creation.\n   * @returns {mixed} - TODO: add return description.\n   * @private\n   */\n  done(...args) {\n    if (typeof args[args.length - 1] === 'function') {\n      // eslint-disable-next-line no-console\n      console.warn('Callback function no longer supported as of winston@3.0.0');\n      args.pop();\n    }","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/winstonjs/winston/blob/ff0b79de8562bb322c390fbc82fe71c11f373428/lib/winston/profiler.js#L7-L43","documentation":"Profiler objects time operations and log a duration through their associated Logger. The constructor strictly validates the argument: it must be a real Logger instance (not a plain object or array), otherwise timing results could never be logged, so it throws.","triggerScenarios":"Calling `new winston.Profiler(...)` (or `logger.startTimer()` internals) with `undefined`, a plain object, an array, or a non-Logger object; also passing something that looks like a logger but was created by another library or an older winston copy (fails the `instanceof Logger` check).","commonSituations":"Duplicated winston in node_modules (two copies -> instanceof mismatch); mocking a logger in tests with a plain object stub then calling startTimer; calling Profiler directly instead of via `logger.startTimer()`.","solutions":["Use `logger.startTimer()` / `profile()` on a real winston Logger instead of constructing Profiler manually.","Ensure exactly one winston version is installed (`npm ls winston`) so `instanceof` checks pass.","Pass the actual Logger instance returned by `winston.createLogger()`, not a stub or plain object.","In tests, use the real Logger or a class that extends it rather than a duck-typed mock."],"exampleFix":"// before\nconst profiler = new winston.Profiler({ log: () => {} }); // plain object\n\n// after\nconst logger = winston.createLogger({ transports: [new winston.transports.Console()] });\nconst timer = logger.startTimer();\ntimer.done({ message: 'work finished' });","handlingStrategy":"type-guard","validationCode":"const Logger = require('winston/lib/winston/logger');\nif (!(maybeLogger instanceof Logger)) {\n  throw new TypeError('Profiler requires an actual winston Logger instance');\n}","typeGuard":"function isRealLogger(x) { return x instanceof require('winston').Logger; }","tryCatchPattern":"try {\n  const p = new winston.Profiler(logger);\n} catch (err) {\n  if (err.message === 'Logger is required for profiling') {\n    const p = logger.startTimer();\n  } else { throw err; }\n}","preventionTips":["Use `logger.startTimer()` / `logger.profile(id)` instead of constructing Profiler directly","Avoid plain-object logger mocks in tests; subclass Logger or use the real one","Deduplicate winston installs (`npm ls winston`) to avoid instanceof mismatches","Pass the createLogger() return value, never wrappers or stubs"],"tags":["winston","argument-validation","profiling","constructor"],"backgroundTag":"missing-required-argument","analyzedSha":"ff0b79de8562bb322c390fbc82fe71c11f373428","analyzedAt":"2026-08-31T13:33:44.585Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}