1

I created a script that puts a list of files into a zip and saves it on in the Cloudflare R2 bucket. The scripts runs until the archive gets closed, after that, it throws the error: Error: The script will never generate a response.

As you see, I catch every possible response, but still, I get this error. Any ideas why?

import { z } from 'zod';
import { ZipWriter, BlobReader, configure } from '@zip.js/zip.js';

// Without this, we get uncaught error due to Workers runtime bug
// See: https://github.com/gildas-lormeau/zip.js/discussions/514
configure({
    useCompressionStream: false,
});

// Payload schema that lists the files to be bundled, their filenames and the archive filename
const schema = z.object({
    archive_filename: z.string().endsWith('.zip'),
    files: z.array(
        z.object({
            r2key: z.string(),
            filename: z.string(),
        })
    ),
});

export default {
    async fetch(request, env, ctx): Promise<Response> {
        // Only POST is supported
        if (request.method !== 'POST') {
            return new Response('Method Not Allowed', { status: 405 });
        }
        const body = await request.json();

        const payload = schema.safeParse(body);
        if (!payload.success) {
            return new Response(JSON.stringify({ status: 'failed', error: payload.error }), {
                status: 409,
                headers: { 'Content-Type': 'application/json' },
            });
        }

        // Use IdentityTransformStream to capture the zip output
        let { readable, writable } = new IdentityTransformStream();

        // Create a ZIP archive stream
        const archive = new ZipWriter(writable);

        // Store all the promises to catch any errors all together later
        let promises: Promise<any>[] = [];

        console.log(payload);

        for (const somefile of payload.data.files) {
            const { r2key, filename } = somefile;
            console.log(r2key);
            console.log(filename);

            // Fetch the file from the R2 bucket
            const fileContent = await env.STORAGE_BUCKET_DEV.get(r2key);
            if (!fileContent) {
                return new Response(`Object not found: ${r2key}`, { status: 404 });
            }

            // Add the file to the ZIP archive
            promises.push(archive.add(filename, new BlobReader(await fileContent.blob())));
            console.log("Item added");
        }

        // Close the archive
        promises.push(archive.close());
        //Everything works till here.


        try {
            // Wait for all files to be added and the archive to be closed
            await Promise.all(promises);

            // Save the ZIP archive to the bucket
            const key = `downloads/${payload.data.archive_filename}`;
            await env.STORAGE_BUCKET_DEV.put(key, readable, {
                httpMetadata: { contentType: 'application/zip' },
            });

            // Return the download URL
            const url = new URL(request.url);
            url.pathname = `/${key}`;
            return new Response(JSON.stringify({ url: url.toString() }), {
                headers: { 'Content-Type': 'application/json' },
            });
        } catch (err) {
            return new Response(
                JSON.stringify({ status: 'error', message: err.toString() }),
                { status: 500, headers: { 'Content-Type': 'application/json' } }
            );
        }

    },
} satisfies ExportedHandler<Env>;

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.