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 },
)
formatterbecomes the default formatter when one is not provided in call-level options.loggerServiceis always reused unless you explicitly disable logging withlogger: false.eventEmitteris injected into every call unless you override viaoptions.event.
Properties:
logger: the injectedImprovedLoggerService.emitter: the injectedEventEmitter2.emit/emitAsync: aliases oflog/logAsync.
Logging methods
All methods accept eventName: Parameters<TFormatter> | string and optional IEventOptions<TFormatter>; options are merged with the constructor defaults.
log/logAsyncwarn/warnAsyncdebug/debugAsyncverbose/verboseAsync
These simply delegate to the corresponding event* helpers, applying the injected emitter/logger.
Error methods
General helpers:
error/errorAsync: return/log usingDefaultErrorby default. Decorated withInjectTraceto populatestackif none is provided.errorResult: wrapserrorin aneverthrow.Err.errorFromFn: executes a callback, returningok(result)orErr(DefaultError)on failure.errorForward: forward/normalize an existing error (instance or class) into aDefaultError, 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 (fallbackInternalServerError) and apply the appropriate logger level.- Dedicated methods for common statuses (each with
*Resultand*FromFnvariants):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
buildOptionsmerges call-level options with the injected emitter/formatter and logger instance. If an error instance orcauseis provided, it ensures astackis present.buildErrorOptionsguarantees anerrorClass(defaulttrue→DefaultError).applyLoggerLevel/applyLoggerLevelByStatus/applyLoggerLevelByErrorsetlogger.level; callers decide whether to preserve an explicit level.applyCauseattaches the original error ascause, 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 },
});
}
}
}