Profiles·Public

winston

semver>=3.0.0 <4.0.0postconditions11functions9last verified2026-06-24coverage score89%

Postconditions: what we check

  • createLogger · missing-error-listener
    warning
    WhencreateLogger() called without .on('error', handler) registered on the returned logger instance
    Returnslogger instance that silently swallows transport errors without error listener
    Required handlingCaller MUST attach an 'error' event listener to the logger instance immediately after createLogger(). Without it, transport failures (file system full, permission denied, network transport errors) are silently lost and logs may be dropped. Use: logger.on('error', (err) => { ... }). Source: Winston README — "the logger also emits an 'error' event if an error occurs within the logger itself which you should handle or suppress"
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[1][2]
  • query · query-unhandled-callback-error
    error
    Whenlogger.query() callback receives err as first argument when any transport query fails (e.g. File transport ENOENT/EACCES on log read, or transport does not support query method). Callers that omit the err check silently receive null/undefined results.
    Required handlingCaller MUST check the first argument to the callback: if (err) { handle or rethrow }. Ignoring err causes silent failures in log monitoring dashboards and audit UIs.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[3]
  • transports.File · file-transport-missing-per-transport-error-listener
    warning
    Whennew transports.File() created without transport.on('error', handler). Filesystem errors (ENOSPC disk full, EACCES permission denied, ENOENT missing directory) during log writes are emitted on the transport instance itself — NOT on the parent logger. A logger.on('error') listener does not catch transport-level errors.
    Required handlingAfter creating a File transport, attach: transport.on('error', (err) => { ... }). This is separate from and required in addition to logger.on('error'). Without it, log file write failures are silently lost and logs are dropped without any alert.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[4][1]
  • transports.File · file-transport-constructor-throws-on-invalid-options
    error
    Whennew transports.File() called with both 'stream' and 'filename'/'dirname' options simultaneously, or with neither a filename nor a stream. Constructor throws synchronously. When File transports are created dynamically (per-tenant log files, runtime-configured paths), uncaught throws crash the request handler.
    ThrowsError (synchronous, at construction time)
    Required handlingWrap dynamic new transports.File() calls in try/catch when filename is derived from runtime input. Validate that mutually exclusive options are not passed together.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • transports.Http · http-transport-warn-not-error-on-failure
    warning
    Whentransports.Http used without a 'warn' event listener. HTTP 4xx/5xx responses and connection errors trigger this.emit('warn', err) on the transport — not 'error'. Code that only attaches transport.on('error', handler) silently misses all network transport failures.
    Required handlingWhen using Http transport and log delivery reliability matters, attach both: transport.on('error', handler) AND transport.on('warn', handler). The 'warn' event carries network failures, not 'error'. Omitting the warn listener means silent log loss to remote aggregators.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5]
  • configure · configure-throws-on-v2-options
    error
    Whenlogger.configure() or createLogger() called with any of the removed winston@2 options: colors, emitErrs, formatters, padLevels, rewriters, stripColors. Throws synchronously with "{ colors, emitErrs, formatters, padLevels, rewriters, stripColors } were removed in winston@3.0.0." Migration codebases frequently pass both old and new options.
    ThrowsError — deprecated option keys present in configure options object
    Required handlingRemove all deprecated v2 option keys before passing to createLogger() or configure(). Use winston.format.* combinators instead of the removed formatters/padLevels/stripColors options. Wrap logger initialization in try/catch when config is loaded from external sources (env vars, config files) that may contain v2-era options.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][6]
  • add · add-throws-on-non-objectmode-transport
    error
    Whenlogger.add() called with a transport that lacks _writableState.objectMode. Throws synchronously with "Transports must WritableStreams in objectMode." Typically surfaces when using third-party custom transports written for winston@2 (non-stream transports) not yet updated for @3.
    ThrowsError — transport is not a WritableStream in objectMode
    Required handlingWrap logger.add() in try/catch when transport type is not known at compile time. Verify third-party transports extend winston-transport (which sets objectMode: true) before dynamically adding them. For per-request transport patterns, validate transport instance before calling add().
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • cli · cli-throws-unconditionally
    error
    Whenlogger.cli() called on any logger instance in winston@3+. Throws synchronously with "Logger.cli() was removed in winston@3.0.0\nUse a custom winston.formats.cli() instead." This is a hard migration trap — winston@2 codebases that call logger.cli() crash at startup after upgrade.
    ThrowsError — Logger.cli() was removed in winston@3.0.0
    Required handlingRemove all logger.cli() calls when upgrading from winston@2 to @3. Replace with winston.format.cli() composed into the logger's format chain: createLogger({ format: winston.format.cli(), transports: [...] }). If logger.cli() is called at startup, the synchronous throw will crash the process before any error handler can attach. Audit migration paths carefully.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][6]
  • exceptions.handle · exceptions-handle-installs-process-exit
    warning
    Whenlogger.exceptions.handle(transport) or createLogger({ exceptionHandlers: [...] }) registers a `process.on('uncaughtException', ...)` listener. When an uncaught exception fires, the handler logs to the registered transports AND calls process.exit(1) after a 3-second timeout (when logger.exitOnError is true, the default). Code that relies on a long-running process being kept alive after the log is written will be terminated.
    Required handlingTo prevent process termination on uncaught exception while still logging, set `exitOnError: false` on the logger options OR pass a function: `exitOnError: (err) => false`. For services where reliability matters, prefer setting up domain-specific error boundaries (express error middleware, async-context try/catch, AbortController) rather than relying on winston's exception handler as a safety net — winston exits the process regardless of whether the log write succeeded.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7][8]
  • exceptions.handle · exception-handler-constructor-requires-logger
    error
    Whennew winston.ExceptionHandler() called without a logger argument. Throws synchronously with "Logger is required to handle exceptions". Encountered when users build a standalone ExceptionHandler outside the auto-created `logger.exceptions` path (e.g. shared exception capture across multiple loggers).
    ThrowsError — Logger is required to handle exceptions
    Required handlingAlways pass a valid Logger instance to `new winston.ExceptionHandler(logger)`. The idiomatic path is to use the auto-created `logger.exceptions` accessor and call `.handle(...transports)` on it — that path is guaranteed to have a logger bound. Avoid manual ExceptionHandler construction unless you have a specific multi-logger coordination requirement.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7]
  • rejections.handle · rejections-handle-installs-process-exit
    warning
    Whenlogger.rejections.handle(transport) or createLogger({ rejectionHandlers: [...] }) registers a `process.on('unhandledRejection', ...)` listener. On unhandled rejection, the handler logs to the registered transports and calls process.exit(1) after a 3-second timeout when `exitOnError` is true (default). Combined with Node 15+'s default `throw` mode on unhandled rejections, this means promises that lose their .catch() WILL terminate the service — even if the promise itself was fire-and-forget.
    Required handlingTreat unhandled rejection capture as a last-resort observability tool, not a safety net. Every async function MUST have explicit error handling at the awaiter / .catch(). If you set `rejectionHandlers` to capture telemetry, set `exitOnError: false` to avoid terminating long-lived services on a single stray promise. For Express/Koa/Nest stacks, rely on framework-provided async error middleware and use `rejections.handle()` only to capture the log of last resort.
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[9][10]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Source code

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Sources: winston

Package: winston Version: 3.x Category: logging (Logging library) Status: ✅ Complete


Official Documentation

Behavioral Requirements

Transport Errors: File write failures, network issues Should add error event listeners to logger and transports Transport failures should not crash application handleExceptions option can mask errors if not configured properly

Contract Rationale

Logger errors are silent by default: Transport failures go unnoticed File transports can fail: Disk full, permissions, path issues Network transports can fail: Connection issues, timeouts handleExceptions requires careful configuration: Can prevent proper error handling

Real-World Evidence (2026-04-02)

  • santiq/bulletproof-nodejs (⭐5k): createLogger without .on('error') — TP violation
  • getmaxun/maxun (⭐15k): createLogger with File transports, no .on('error') — TP violation
  • whyour/qinglong (⭐19k): createLogger with .on('error') — correct, no violation
  • 2/4 repos scanned have the antipattern = 50% prevalence in real world

Created: 2026-02-26 Updated: 2026-04-02 Status: ✅ COMPLETE (evidence_quality upgraded from stub to confirmed)

Need a different package?
Request a profile