Skip to content

How to Debug Cloudflare Workers Runtime Errors

DodaTech 2 min read

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 fetch handler body in a try/catch that logs the error and returns a structured response
  • Stream live logs with wrangler tail --format pretty during development and testing
  • Use wrangler dev for 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 tail output as a datasource in your monitoring system

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro