NestJS-YALC
Table of Contents:
  1. YalcEventService
    1. Constructor
    2. Logging methods
    3. Error methods
    4. Option handling and defaults
    5. Examples

YalcEventService

YalcEventService is the NestJS-facing façade over the event helpers: it injects logger + emitter, applies defaults, and exposes a rich set of logging and error helpers (with neverthrow Result variants) so you can keep event, log, and error handling consistent across your app.

It is also the recommended entry point for orchestrating error logging, domain events, and HTTP-aware error responses based on the DefaultError hierarchy.

Please also see Event helpers, Event module, Logger, Errors, and the higher-level Error handling guide.

For external monitoring, use @nestjs-yalc/observability. It subscribes to the EventManager EventEmitter2 stream and exports YalcEventService events to OpenTelemetry logs, metrics, span events, and exceptions while keeping this service focused on local event/log/error orchestration.

Constructor

constructor(
  loggerService: ImprovedLoggerService,
  eventEmitter: EventEmitter2,
  options?: { formatter?: EventNameFormatter },
)
  • formatter becomes the default formatter when one is not provided in call-level options.
  • loggerService is always reused unless you explicitly disable logging with logger: false.
  • eventEmitter is injected into every call unless you override via options.event.

Properties:

  • logger: the injected ImprovedLoggerService.
  • emitter: the injected EventEmitter2.
  • emit / emitAsync: aliases of log / logAsync.

Logging methods

All methods accept eventName: Parameters<TFormatter> | string and optional IEventOptions<TFormatter>; options are merged with the constructor defaults.

  • log / logAsync
  • warn / warnAsync
  • debug / debugAsync
  • verbose / verboseAsync

These simply delegate to the corresponding event* helpers, applying the injected emitter/logger.

Error methods

General helpers:

  • error / errorAsync: return/log using DefaultError by default. Decorated with InjectTrace to populate stack if none is provided.
  • errorResult: wraps error in a neverthrow.Err.
  • errorFromFn: executes a callback, returning ok(result) or Err(DefaultError) on failure.
  • errorForward: forward/normalize an existing error (instance or class) into a DefaultError, preserving/merging payloads. Logger level is inferred from the status code unless explicitly set.
  • errorForwardResult / errorForwardFromFn: neverthrow variants of forwarding helpers.

HTTP-specific helpers:

  • errorHttp(eventName, code, options?): map an HTTP status to a corresponding error class (fallback InternalServerError) and apply the appropriate logger level.
  • Dedicated methods for common statuses (each with *Result and *FromFn variants): errorBadRequest, errorUnauthorized, errorPaymentRequired, errorForbidden, errorNotFound, errorMethodNotAllowed, errorNotAcceptable, errorConflict, errorGone, errorUnsupportedMediaType, errorUnprocessableEntity, errorTooManyRequests, errorInternalServerError, errorNotImplemented, errorBadGateway, errorServiceUnavailable, errorGatewayTimeout.

HTTP helpers select the matching error class and apply the status-derived log level (500+ → error, 429 → warn, otherwise → log), including when a logger level is supplied; logger: false still disables logging. errorForward instead preserves an explicit logger option and otherwise derives the level from the forwarded status. Forwarding preserves an existing DefaultError instance; ordinary Error instances are normalized to a new DefaultError. It merges data and response with call-level fields taking precedence. Keep private diagnostics in data and client-safe content in response.

error returns an error synchronously; errorResult returns an Err synchronously. Throw the error explicitly when desired. errorAsync resolves with that error after awaited primary/alias emissions complete, or rejects with an awaited listener’s failure. It defaults to event.await: true; explicit false opts out of listener completion. String aliases inherit this setting; object aliases choose their own await. *FromFn awaits the callback but uses synchronous error/Result helpers, so it does not wait for emission completion. See helper completion and rejection semantics.

Option handling and defaults

  • buildOptions merges call-level options with the injected emitter/formatter and logger instance. If an error instance or cause is provided, it ensures a stack is present.
  • buildErrorOptions guarantees an errorClass (default true → DefaultError).
  • applyLoggerLevel/applyLoggerLevelByStatus/applyLoggerLevelByError set logger.level; callers decide whether to preserve an explicit level.
  • applyCause attaches the original error as cause, enriching the payload when forwarded.
  • Pending promises triggered by event emission are registered with the global promise tracker.

Examples

Module wiring with Nest:

import { EventEmitterModule } from "@nestjs/event-emitter";
import { EventModule } from "@nestjs-yalc/event-manager";

@Module({
  imports: [
    EventEmitterModule.forRoot(),
    EventModule.forRootAsync({
      loggerProvider: { context: "AppEvents" },
    }),
  ],
})
export class AppModule {}

Usage in a provider:

import { YalcEventService } from "@nestjs-yalc/event-manager";

@Injectable()
export class UserService {
  constructor(private readonly events: YalcEventService) {}

  async create(user: CreateUserDto) {
    try {
      // Emit + log a success event
      await this.events.log(["user", "created"], {
        data: { userId: user.id },
        event: { await: true },
      });
      return user;
    } catch (error) {
      // Forward and log the error with merged context
      throw this.events.errorForward("user.create.failed", error, {
        data: { userId: user.id },
      });
    }
  }
}