The SMTPServer class extends EventEmitter and emits events for connection lifecycle and errors. You can listen to these events to monitor server activity, implement logging, or integrate with external systems.
Listening to Events
const { SMTPServer } = require ( 'smtp-server' );
const server = new SMTPServer ({ /* options */ });
server . on ( 'connect' , data => {
console . log ( 'New connection:' , data );
});
server . on ( 'error' , err => {
console . error ( 'Server error:' , err );
});
server . on ( 'close' , () => {
console . log ( 'Server closed' );
});
Events
connect
Emitted when a new client connection is established and ready to proceed (after HELO/EHLO or XCLIENT/XFORWARD).
This event is emitted after the connection is validated, not immediately when the socket connects. Use the onConnect handler for early connection control.
Event Data
Unique connection identifier
Hostname provided by client in HELO/EHLO
Client hostname from reverse DNS or [IP]
Example
Connection Logger
Connection Tracking
Metrics Collection
server . on ( 'connect' , data => {
console . log ( `[ ${ data . id } ] Connection from ${ data . remoteAddress } : ${ data . remotePort } ` );
console . log ( `[ ${ data . id } ] Client hostname: ${ data . clientHostname } ` );
console . log ( `[ ${ data . id } ] Identified as: ${ data . hostNameAppearsAs } ` );
});
error
Emitted when an error occurs with the server or a connection.
You should always listen to the error event. Unhandled error events can crash your application.
Event Data
Error object with the following properties: Error code (e.g., 'ECONNRESET', 'TLSError')
Client IP address (if connection-related)
SMTP response code sent to client (if applicable)
Additional metadata about the error context
Example
Basic Error Handler
Detailed Error Logging
Error Categorization
server . on ( 'error' , err => {
console . error ( 'SMTP Server Error:' , err . message );
if ( err . code === 'EADDRINUSE' ) {
console . error ( 'Port already in use!' );
process . exit ( 1 );
}
});
close
Emitted when the server is closed and no longer accepting connections.
This event is emitted after all connections have been closed and the server has fully shut down.
Event Data
This event has no data payload.
Example
Graceful Shutdown
Restart on Close
server . on ( 'close' , () => {
console . log ( 'SMTP server has been shut down' );
// Clean up resources
database . disconnect ();
cache . close ();
console . log ( 'All resources cleaned up' );
});
// Initiate shutdown
process . on ( 'SIGTERM' , () => {
console . log ( 'Received SIGTERM, closing server...' );
server . close ();
});
Complete Example
Here’s a comprehensive example using all events:
const { SMTPServer } = require ( 'smtp-server' );
// Connection tracking
const connections = new Map ();
let totalConnections = 0 ;
let totalErrors = 0 ;
const server = new SMTPServer ({
logger: true ,
onAuth ( auth , session , callback ) {
// Implement authentication
callback ( null , { user: auth . username });
},
onData ( stream , session , callback ) {
stream . on ( 'end' , () => {
callback ( null , 'Message queued' );
});
}
});
// Track new connections
server . on ( 'connect' , data => {
totalConnections ++ ;
connections . set ( data . id , {
remoteAddress: data . remoteAddress ,
hostname: data . clientHostname ,
connectedAt: new Date (),
authenticated: false
});
console . log ( `[CONNECT] ${ data . id } from ${ data . remoteAddress } ` );
console . log ( `Active: ${ connections . size } , Total: ${ totalConnections } ` );
});
// Handle errors
server . on ( 'error' , err => {
totalErrors ++ ;
if ( err . remoteAddress ) {
console . error ( `[ERROR] ${ err . remoteAddress } : ${ err . message } ` );
} else {
console . error ( `[ERROR] Server: ${ err . message } ` );
}
// Alert on high error rate
if ( totalErrors > 100 ) {
console . error ( '[ALERT] High error rate detected!' );
}
});
// Handle server close
server . on ( 'close' , () => {
console . log ( '[CLOSE] Server shut down' );
console . log ( `Final stats - Total connections: ${ totalConnections } , Errors: ${ totalErrors } ` );
connections . clear ();
});
// Start server
server . listen ( 2525 , () => {
console . log ( 'SMTP server listening on port 2525' );
});
// Graceful shutdown
process . on ( 'SIGTERM' , () => {
console . log ( 'Shutting down gracefully...' );
server . close (() => {
process . exit ( 0 );
});
});
Event Timing
Events are emitted in this typical order:
connect - After client completes HELO/EHLO (or XCLIENT/XFORWARD if enabled)
error - Whenever an error occurs (can happen at any time)
close - When server.close() completes
The connect event may be delayed if useXClient or useXForward options are enabled, as the server waits for these commands before emitting the event.
See Also