Production-ready error logger for frontend applications with backend and AWS S3 support
npm install tetrabillboard-error-loggerwindow.onerror - Global JavaScript errors
console.error - Console error messages
bash
npm install @tetrabillboard/error-logger
`
Quick Start
$3
`javascript
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
endpoint: 'https://api.tetrabillboard.com/log-error',
appName: 'cart-app',
environment: 'production',
release: 'v1.2.3'
});
`
$3
`javascript
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
});
`
$3
`javascript
import { initErrorLogger } from '@tetrabillboard/error-logger';
initErrorLogger({
appName: 'cart-app',
environment: 'production',
s3: {
presignedUrl: 'https://my-bucket.s3.amazonaws.com/...?X-Amz-Signature=...'
}
});
`
$3
`javascript
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.
$3
`javascript
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 | - | 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
$3
Initialize the error logger with configuration.
`javascript
import { initErrorLogger } from '@tetrabillboard/error-logger';
const logger = initErrorLogger({
endpoint: 'https://api.example.com/errors',
appName: 'my-app',
environment: 'production'
});
`
$3
Manually log an error.
`javascript
import { logError } from '@tetrabillboard/error-logger';
try {
// Some code
} catch (error) {
logError(error, { userId: '123', action: 'checkout' });
}
`
$3
Log a message with severity level.
`javascript
import { logMessage } from '@tetrabillboard/error-logger';
logMessage('Payment processing failed', 'error', {
orderId: '456',
amount: 99.99
});
`
$3
Flush pending errors immediately.
`javascript
import { flush } from '@tetrabillboard/error-logger';
// Before page unload
window.addEventListener('beforeunload', async () => {
await flush();
});
`
$3
Remove error handlers and cleanup.
`javascript
import { destroyErrorLogger } from '@tetrabillboard/error-logger';
destroyErrorLogger();
`
$3
Get the current logger instance.
`javascript
import { getErrorLogger } from '@tetrabillboard/error-logger';
const logger = getErrorLogger();
if (logger) {
logger.logError(new Error('Something went wrong'));
}
`
Advanced Usage
$3
`javascript
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;
}
});
`
$3
`javascript
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'
}
});
`
$3
`javascript
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;
}
}
`
$3
`javascript
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');
`
$3
`javascript
// 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 ;
}
export default MyApp;
`
Error Payload Structure
Errors are sent in the following format:
`typescript
{
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';
}
`
$3
When batching is enabled:
`json
{
"errors": [
{ / error payload / },
{ / error payload / }
]
}
`
Backend API Requirements
Your backend endpoint should:
1. Accept POST requests
2. Parse application/json content type
3. Return appropriate HTTP status codes:
- 200-299: Success
- 429: Rate limit (will retry)
- 500-599: Server error (will retry)
$3
`javascript
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:
- fetch API
- Promise
- WeakSet
TypeScript
The package includes TypeScript definitions out of the box.
`typescript
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
`bash
Install dependencies
npm install
Build the package
npm run build
Clean build artifacts
npm run clean
``