How to Debug Cloudflare Workers Runtime Errors
In this tutorial, you'll learn about How to Debug Cloudflare Workers Runtime Errors. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
The Problem
Your Cloudflare Worker returns Internal Server Error (HTTP 500) or throws a runtime error that does not appear in the logs. Cloudflare Workers run on V8 isolates with limited console output compared to Node.js. Without proper error handling, any uncaught exception crashes the worker and returns a generic 500 response with no details about what went wrong.
Quick Fix
1. Add structured error logging to every request handler
export default {
async fetch(request, env, ctx) {
try {
const url = new URL(request.url);
if (url.pathname === '/api/data') {
const data = await env.KV.get('config', 'json');
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' },
});
}
return new Response('Not found', { status: 404 });
} catch (error) {
console.error('Request failed:', {
url: request.url,
method: request.method,
error: error.message,
stack: error.stack,
});
return new Response(
JSON.stringify({ error: 'Internal server error' }),
{ status: 500, headers: { 'Content-Type': 'application/json' } }
);
}
},
};
2. Use wrangler tail for live log streaming
npx wrangler tail --format pretty
Expected output:
2024-01-15 10:30:00.000 REQUEST GET /api/data
2024-01-15 10:30:00.050 LOG Request failed: {"url":"https://worker.example.com/api/data","error":"KV entry not found"}
2024-01-15 10:30:00.050 RESPONSE 500
3. View errors in the Cloudflare Dashboard
Open the Cloudflare Dashboard:
Workers & Pages → Select your Worker → Logs
Filter by Outcome: exception to see only error events.
4. Handle unhandled promise rejections
addEventListener('unhandledrejection', (event) => {
console.error('Unhandled rejection:', event.reason);
event.preventDefault();
});
5. Debug locally with wrangler dev
npx wrangler dev --local --test-scheduled
Expected output:
⬣ Listening at http://localhost:8787
Test locally:
curl http://localhost:8787/api/data
6. Avoid incompatibility with Node.js APIs
// Do not use Node.js-specific APIs:
// const crypto = require('crypto');
// const fs = require('fs');
// Use the Web standard APIs:
const key = await crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
Additional Troubleshooting
# Check the error message and stack trace for more context
echo "Review the full error output to identify the root cause"
If the above steps do not resolve the issue, examine the complete error message and stack trace. Often the key detail is in the middle of the traceback rather than the final line. Search for the error message in the project documentation or issue tracker for additional solutions.
Prevention
- Wrap every
fetchhandler body in atry/catchthat logs the error and returns a structured response - Stream live logs with
wrangler tail --format prettyduring development and testing - Use
wrangler devfor local debugging before deploying to production - Avoid Node.js built-in modules — use Web APIs that are available in the Workers runtime
- Set up
wrangler tailoutput as a datasource in your monitoring system
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro