tetrabillboard-error-logger
v1.0.0
Published
Production-ready error logger for frontend applications with backend and AWS S3 support
Maintainers
Readme
@tetrabillboard/error-logger
Production-ready error logger for frontend applications with backend API and AWS S3 support.
Features
✅ Automatic Error Capture
window.onerror- Global JavaScript errorsconsole.error- Console error messages- Unhandled Promise Rejections
✅ Flexible Transport Options
- Send to backend API endpoint
- Upload directly to AWS S3 (presigned URL or credentials)
- Support for both simultaneously
✅ Smart Batching
- Queue errors and send in batches
- Configurable batch size and interval
- Automatic flush on batch size threshold
✅ Retry Logic
- Exponential backoff for failed requests
- Configurable retry attempts
- Smart retry for 5xx and 429 errors
✅ TypeScript Support
- Full TypeScript definitions
- Type-safe configuration
- IntelliSense support
✅ Production Ready
- Zero dependencies
- Lightweight (~5KB gzipped)
- Framework agnostic
- Browser environment detection
Installation
npm install @tetrabillboard/error-loggerQuick Start
Basic Usage (Backend Endpoint)
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
endpoint: 'https://api.tetrabillboard.com/log-error',
appName: 'cart-app',
environment: 'production',
release: 'v1.2.3'
});With Batching
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
endpoint: 'https://api.tetrabillboard.com/log-error',
appName: 'cart-app',
environment: 'production',
release: 'v1.2.3',
batch: true,
batchSize: 10,
batchInterval: 5000 // 5 seconds
});With AWS S3 (Presigned URL)
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
appName: 'cart-app',
environment: 'production',
s3: {
presignedUrl: 'https://my-bucket.s3.amazonaws.com/...?X-Amz-Signature=...'
}
});With AWS S3 (Credentials)
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
appName: 'cart-app',
environment: 'production',
s3: {
bucket: 'my-error-logs',
region: 'us-east-1',
accessKeyId: 'YOUR_ACCESS_KEY',
secretAccessKey: 'YOUR_SECRET_KEY',
keyPrefix: 'error-logs/'
}
});Note: S3 upload with credentials requires implementing AWS SDK signing. For production, use presigned URLs or implement AWS SDK integration.
Dual Transport (Backend + S3)
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
endpoint: 'https://api.tetrabillboard.com/log-error',
appName: 'cart-app',
environment: 'production',
release: 'v1.2.3',
s3: {
presignedUrl: 'https://my-bucket.s3.amazonaws.com/...?X-Amz-Signature=...'
}
});Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| endpoint | string | - | Backend API endpoint URL |
| appName | string | Required | Application identifier |
| environment | string | Required | Environment (production, staging, etc.) |
| release | string | - | Release version |
| batch | boolean | false | Enable error batching |
| batchSize | number | 10 | Number of errors per batch |
| batchInterval | number | 5000 | Batch flush interval (ms) |
| debug | boolean | false | Enable debug logging |
| s3 | S3Config | - | AWS S3 configuration |
| headers | Record<string, string> | - | Custom HTTP headers |
| maxRetries | number | 3 | Maximum retry attempts |
| autoCaptureErrors | boolean | true | Auto-capture errors on init |
| beforeSend | function | - | Filter/modify errors before sending |
API Reference
initErrorLogger(config)
Initialize the error logger with configuration.
import { initErrorLogger } from '@tetrabillboard/error-logger';
const logger = initErrorLogger({
endpoint: 'https://api.example.com/errors',
appName: 'my-app',
environment: 'production'
});logError(error, context?)
Manually log an error.
import { logError } from '@tetrabillboard/error-logger';
try {
// Some code
} catch (error) {
logError(error, { userId: '123', action: 'checkout' });
}logMessage(message, level?, context?)
Log a message with severity level.
import { logMessage } from '@tetrabillboard/error-logger';
logMessage('Payment processing failed', 'error', {
orderId: '456',
amount: 99.99
});flush()
Flush pending errors immediately.
import { flush } from '@tetrabillboard/error-logger';
// Before page unload
window.addEventListener('beforeunload', async () => {
await flush();
});destroyErrorLogger()
Remove error handlers and cleanup.
import { destroyErrorLogger } from '@tetrabillboard/error-logger';
destroyErrorLogger();getErrorLogger()
Get the current logger instance.
import { getErrorLogger } from '@tetrabillboard/error-logger';
const logger = getErrorLogger();
if (logger) {
logger.logError(new Error('Something went wrong'));
}Advanced Usage
Custom Error Filtering
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
endpoint: 'https://api.example.com/errors',
appName: 'my-app',
environment: 'production',
beforeSend: (payload) => {
// Ignore specific errors
if (payload.message.includes('Script error')) {
return false;
}
// Add custom fields
payload.context = {
...payload.context,
sessionId: getSessionId()
};
return payload;
}
});Custom Headers
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
endpoint: 'https://api.example.com/errors',
appName: 'my-app',
environment: 'production',
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'X-Custom-Header': 'value'
}
});React Integration
import React from 'react';
import { initErrorLogger, logError } from '@tetrabillboard/error-logger';
class ErrorBoundary extends React.Component {
componentDidMount() {
initErrorLogger({
endpoint: 'https://api.example.com/errors',
appName: 'react-app',
environment: process.env.NODE_ENV,
release: process.env.REACT_APP_VERSION
});
}
componentDidCatch(error, errorInfo) {
logError(error, { componentStack: errorInfo.componentStack });
}
render() {
return this.props.children;
}
}Vue.js Integration
import { createApp } from 'vue';
import { initErrorLogger, logError } from '@tetrabillboard/error-logger';
import App from './App.vue';
const app = createApp(App);
initErrorLogger({
endpoint: 'https://api.example.com/errors',
appName: 'vue-app',
environment: import.meta.env.MODE,
release: import.meta.env.VITE_APP_VERSION
});
app.config.errorHandler = (err, vm, info) => {
logError(err, {
component: vm?.$options.name,
info
});
};
app.mount('#app');Next.js Integration
// pages/_app.js
import { useEffect } from 'react';
import { initErrorLogger } from '@tetrabillboard/error-logger';
function MyApp({ Component, pageProps }) {
useEffect(() => {
initErrorLogger({
endpoint: 'https://api.example.com/errors',
appName: 'nextjs-app',
environment: process.env.NODE_ENV,
release: process.env.NEXT_PUBLIC_VERSION,
batch: true
});
}, []);
return <Component {...pageProps} />;
}
export default MyApp;Error Payload Structure
Errors are sent in the following format:
{
message: string; // Error message
stack?: string; // Stack trace
type: string; // Error type/name
timestamp: string; // ISO 8601 timestamp
appName: string; // Your app name
environment: string; // Environment
release?: string; // Release version
url: string; // Page URL
userAgent: string; // Browser user agent
lineNumber?: number; // Line number
columnNumber?: number; // Column number
filename?: string; // Source filename
context?: object; // Custom context
level: 'error' | 'warning' | 'info';
}Batch Format
When batching is enabled:
{
"errors": [
{ /* error payload */ },
{ /* error payload */ }
]
}Backend API Requirements
Your backend endpoint should:
- Accept
POSTrequests - Parse
application/jsoncontent type - Return appropriate HTTP status codes:
200-299: Success429: Rate limit (will retry)500-599: Server error (will retry)
Example Express.js Handler
app.post('/log-error', express.json(), (req, res) => {
const error = req.body;
// Single error
if (error.message) {
console.error('Error received:', error);
// Store in database, forward to monitoring service, etc.
}
// Batch errors
if (error.errors && Array.isArray(error.errors)) {
console.error('Batch errors received:', error.errors.length);
error.errors.forEach(err => {
// Process each error
});
}
res.status(200).json({ success: true });
});Browser Support
- Chrome/Edge: Latest 2 versions
- Firefox: Latest 2 versions
- Safari: Latest 2 versions
- iOS Safari: Latest 2 versions
- Chrome Android: Latest version
Requires:
fetchAPIPromiseWeakSet
TypeScript
The package includes TypeScript definitions out of the box.
import {
initErrorLogger,
ErrorLoggerConfig,
ErrorPayload
} from '@tetrabillboard/error-logger';
const config: ErrorLoggerConfig = {
endpoint: 'https://api.example.com/errors',
appName: 'my-app',
environment: 'production',
batch: true
};
initErrorLogger(config);Development
# Install dependencies
npm install
# Build the package
npm run build
# Clean build artifacts
npm run cleanLicense
MIT © Tetrabillboard
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Support
For issues and questions, please open a GitHub issue at: https://github.com/tetrabillboard/error-logger/issues
