Closed justindjeumenet closed 1 week ago
Hello,
Here is the compatibility matrix of node apis with wrangler and workerd https://workers-nodejs-compat-matrix.pages.dev/
If you enable nodejs_compat
with wrangler version >3.78.10. Most of the fs
library should be available for you. I hope this helps :)
Found this link, where it explains why you are getting the error and a space where you can propose the APIs that you want in workerd.
Here is the compatibility matrix of node apis with wrangler and workerd https://workers-nodejs-compat-matrix.pages.dev/
One caveat here is that the fs API are mocked because you can not access to a disk in the worker runtime. There will probably be some work on this to support a virtual file system in the future.
But for now and coming back to the problem, the issue is that some package is trying to access the file system (fs).
Can you setup your code to attach a file from somewhere else than the file system? (i.e. inline, network, ...)
Hey @shashankboosi and @vicb !! I am using node v22.9.0, wrangler version 2.80.1.
Here is my wrangler.toml file:
#:schema node_modules/wrangler/config-schema.json
name = "xxxxxxxxxxxxxxxxx"
main = ".worker-next/index.mjs"
compatibility_date = "2024-09-25"
compatibility_flags = ["nodejs_compat"]
# Minification helps to keep the Worker bundle size down and improve start up time.
minify = true
# Use the new Workers + Assets to host the static frontend files
assets = { directory = ".worker-next/assets", binding = "ASSETS" }
[[kv_namespaces]]
binding = "NEXT_CACHE_WORKERS_KV"
id = "xxxxxxxxxxxxxxxxxxxxxxxxx"
[observability]
enabled = true
Here is the code causing the issues:
export async function POST(req: Request) {
sendgrid.setApiKey(process.env.SENDGRID_API_KEY!);
try{
const formData = await req.formData();
const username = formData.get('username') as string;
const description = formData.get('description') as string;
const date = formData.get('date') as string;
const fileCount = +(formData.get('file-count') as string);
const files: File[] = [];
for (let i = 0; i < fileCount; i++)
files.push(formData.get('file_' + i) as File);
const attachments = [];
const id = nanoid();
let i = 1;
for (const file of files) {
const arrayBuffer = await file.arrayBuffer();
const name = `${id}_${i}`;
const fileType = file.name.split('.').at(-1);
const command = new PutObjectCommand({
Bucket: process.env.AWS_BUCKET_NAME,
Body: arrayBuffer,
Key: `customers-support-images/${name}.${fileType}`
});
await s3Client.send(command);
attachments.push({
filename: file.name,
content: Buffer.from(arrayBuffer).toString('base64'),
});
i++;
}
const html = await render(SupportTicketEmail({ username, description, date }));
const options: any = {
from: 'xxxxxxxxxxxxxxxxxxxxxx',
to: [xxxxxxxxxxxxxxxxx],
subject: `New Support Ticket from ${username}`,
html,
attachments
};
await sendgrid.send(options);
// Return success response
return new Response(JSON.stringify({ success: true, message: 'Email sent successfully' }), {
headers: { 'Content-Type': 'application/json' },
status: 200
});
} catch (error: any) {
console.error('Error sending email:', error.message);
return new Response(JSON.stringify({ success: false, message: 'Failed to send email', error: error.message }), {
headers: { 'Content-Type': 'application/json' },
status: 500
});
}
}
This piece of code works fine and is so fast with my actual cloud provider but I want migrate to cloudflare worker and "hopefully" reduce my cloud costs.
The issue seems to be linked to sendgrid accessing the file system.
One thing I would suggest: create a striped down example reproducing the issue starting from a simple worker example npm create cloudflare@latest
. Make this repro available in a github repo.
They you can start a discussion about the sendgrid package here.
You can also check with the sendgrip community why they have to use the file system and if there is a way around.
Hey @vicb! It is not just SendGrid, I have the same issue when I try to attach a file and send it to AWS S3. Same error as well when I try to get a file from AWS S3. I am wondering if you guys have an example with reading a file or involving the module fs. thanks
Ah, sorry for the misunderstanding, you can not use fs
because the runtime does not have access to disk.
You can download an S3 file to a Buffer or send a Buffer to S3 not you will not be access to save/load it to/from disk because there is no disk.
Does that make sense?
@vicb Sorry I do not understand your explanation. The code I provided above is what recommended by AWS S3 and SendGrid. You are asking to do differently and do you have an example of code please? I am trying to follow the code example from AWS S3 and SendGrid. I will appreciate it so much if you can provide an example code please.
Thanks
I don't. Maybe try to check other SendGrid sample. You can also ask on the Cloudflare Discord. Hope this helps
Not related to OpenNext (but to node compatibility)
Hey guys!
I am sending an email with attachment from rsc api folder and I got this. Does that mean this is something not yet in Worker? Any help guys!! Thank you