@ethersproject/logger is a TypeScript logging and error management library designed specifically for the ethers.js ecosystem. It provides structured logging with configurable verbosity levels, comprehensive error creation and formatting capabilities, and specialized validation methods for safe blockchain operations.
npm install @ethersproject/loggerimport { Logger, LogLevel, ErrorCode } from "@ethersproject/logger";For CommonJS:
const { Logger, LogLevel, ErrorCode } = require("@ethersproject/logger");import { Logger, LogLevel, ErrorCode } from "@ethersproject/logger";
// Create a logger instance
const logger = new Logger("myapp/1.0.0");
// Basic logging
logger.info("Application started");
logger.warn("This is a warning");
logger.debug("Debug information");
// Error creation and throwing
try {
logger.throwArgumentError("Invalid address", "address", "0xInvalid");
} catch (error) {
console.log(error.message); // Includes formatted parameters
console.log(error.code); // ErrorCode.INVALID_ARGUMENT
}
// Validation helpers
logger.checkArgumentCount(2, 2, "function requires exactly 2 arguments");
logger.checkSafeUint53(42, "value must be a safe integer");
// Global logger usage
const globalLogger = Logger.globalLogger();
Logger.setLogLevel(LogLevel.ERROR); // Only show errorsThe @ethersproject/logger package is built around three core components:
The library supports both instance-based and global singleton patterns, with configurable error censorship and detailed parameter logging for debugging blockchain applications.
The main logging and error management class with comprehensive error handling capabilities.
class Logger {
readonly version: string;
static errors: typeof ErrorCode;
static levels: typeof LogLevel;
constructor(version: string);
// Instance logging methods
_log(logLevel: LogLevel, args: Array<any>): void;
debug(...args: Array<any>): void;
info(...args: Array<any>): void;
warn(...args: Array<any>): void;
// Error creation and throwing
makeError(message: string, code?: ErrorCode, params?: any): Error;
throwError(message: string, code?: ErrorCode, params?: any): never;
throwArgumentError(message: string, name: string, value: any): never;
// Validation and assertion methods
assert(condition: any, message: string, code?: ErrorCode, params?: any): void;
assertArgument(condition: any, message: string, name: string, value: any): void;
checkNormalize(message?: string): void;
checkSafeUint53(value: number, message?: string): void;
checkArgumentCount(count: number, expectedCount: number, message?: string): void;
checkNew(target: any, kind: any): void;
checkAbstract(target: any, kind: any): void;
// Static methods
static globalLogger(): Logger;
static setCensorship(censorship: boolean, permanent?: boolean): void;
static setLogLevel(logLevel: LogLevel): void;
static from(version: string): Logger;
}Usage Examples:
import { Logger, ErrorCode } from "@ethersproject/logger";
const logger = new Logger("mypackage/1.0.0");
// Structured error creation
const error = logger.makeError("Transaction failed", ErrorCode.CALL_EXCEPTION, {
address: "0x742d35Cc6634C0532925a3b8D4060C0F5C9F8A67",
method: "transfer(address,uint256)",
transaction: { to: "0x...", data: "0x...", value: "1000" }
});
// Validation with custom messages
logger.checkArgumentCount(args.length, 2, "transfer function");
logger.assertArgument(isAddress(to), "invalid address format", "to", to);
// Safe integer validation
logger.checkSafeUint53(amount, "amount exceeds safe integer range");Hierarchical logging levels for controlling output verbosity.
enum LogLevel {
DEBUG = "DEBUG",
INFO = "INFO",
WARNING = "WARNING",
ERROR = "ERROR",
OFF = "OFF"
}Usage Examples:
import { Logger, LogLevel } from "@ethersproject/logger";
// Set global log level
Logger.setLogLevel(LogLevel.WARNING); // Only show warnings and errors
// Instance-level logging
const logger = new Logger("test/1.0.0");
logger.debug("This won't show"); // Below WARNING threshold
logger.warn("This will show"); // At WARNING level
logger.info("This won't show"); // Below WARNING thresholdComprehensive error categorization system covering all types of errors in the ethers.js ecosystem.
enum ErrorCode {
// Generic Errors
UNKNOWN_ERROR = "UNKNOWN_ERROR",
NOT_IMPLEMENTED = "NOT_IMPLEMENTED",
UNSUPPORTED_OPERATION = "UNSUPPORTED_OPERATION",
NETWORK_ERROR = "NETWORK_ERROR",
SERVER_ERROR = "SERVER_ERROR",
TIMEOUT = "TIMEOUT",
// Operational Errors
BUFFER_OVERRUN = "BUFFER_OVERRUN",
NUMERIC_FAULT = "NUMERIC_FAULT",
// Argument Errors
MISSING_NEW = "MISSING_NEW",
INVALID_ARGUMENT = "INVALID_ARGUMENT",
MISSING_ARGUMENT = "MISSING_ARGUMENT",
UNEXPECTED_ARGUMENT = "UNEXPECTED_ARGUMENT",
// Blockchain Errors
CALL_EXCEPTION = "CALL_EXCEPTION",
INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS",
NONCE_EXPIRED = "NONCE_EXPIRED",
REPLACEMENT_UNDERPRICED = "REPLACEMENT_UNDERPRICED",
UNPREDICTABLE_GAS_LIMIT = "UNPREDICTABLE_GAS_LIMIT",
TRANSACTION_REPLACED = "TRANSACTION_REPLACED",
// Interaction Errors
ACTION_REJECTED = "ACTION_REJECTED"
}Usage Examples:
import { Logger, ErrorCode } from "@ethersproject/logger";
const logger = new Logger("wallet/1.0.0");
// Blockchain-specific errors
logger.throwError("Transaction failed", ErrorCode.CALL_EXCEPTION, {
address: contractAddress,
method: "transfer(address,uint256)",
args: [recipient, amount]
});
// Argument validation errors
logger.throwArgumentError("Address must be 42 characters", "address", userInput);
// Network operation errors
logger.throwError("Failed to connect", ErrorCode.NETWORK_ERROR, {
url: rpcUrl,
timeout: 5000
});Control error message visibility for production environments:
import { Logger } from "@ethersproject/logger";
// Enable error censorship (can be reversed)
Logger.setCensorship(true);
// Enable permanent censorship (cannot be reversed)
Logger.setCensorship(true, true);
const logger = new Logger("prod/1.0.0");
logger.makeError("Sensitive data: 0x1234"); // Returns "censored error"Singleton pattern for application-wide logging:
import { Logger, LogLevel } from "@ethersproject/logger";
// Get global singleton
const globalLogger = Logger.globalLogger();
// Configure globally
Logger.setLogLevel(LogLevel.ERROR);
Logger.setCensorship(false);
// Use anywhere in application
globalLogger.info("Global message");Structured error information with automatic parameter formatting:
import { Logger, ErrorCode } from "@ethersproject/logger";
const logger = new Logger("debug/1.0.0");
const error = logger.makeError("Operation failed", ErrorCode.CALL_EXCEPTION, {
transaction: { to: "0x742d35Cc", value: "1000", gasLimit: "21000" },
blockNumber: 12345678,
gasUsed: "21000",
data: new Uint8Array([0x12, 0x34, 0x56])
});
// Error message includes formatted parameters:
// "Operation failed (transaction={...}, blockNumber=12345678, gasUsed="21000",
// data=Uint8Array(0x123456), code=CALL_EXCEPTION, version=debug/1.0.0)"const version: string; // "logger/5.8.0"The package exports its version string for compatibility checking and debugging purposes.