You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Skipper与Sails上传流时,写入缓冲区触发路径错误

Fixing "TypeError: path must be a string or Buffer" with skipper-better-s3

The error you're hitting comes from a common gotcha with skipper-better-s3's metadata handling: filesUploaded[0].extra.fd isn't a valid local file path or Buffer—it's actually the S3 object key (the path to your file inside the S3 bucket), which adapter.read() can't process directly. Here's how to fix this properly:

Corrected Code Example

const adapter = require('skipper-better-s3')(options);
const receiver = adapter.receive({dirname: "/original"});
const upstream = req.file('file');

upstream.upload(receiver, function(err, filesUploaded){
    if (err) {
        console.error('Upload failed:', err);
        return;
    }

    // Grab the S3 object key from the uploaded file's metadata
    const s3ObjectKey = filesUploaded[0].extra.fd;
    
    // Use the adapter's pre-configured S3 client to fetch the file
    adapter.s3.getObject({
        Bucket: options.bucket, // Match the bucket name from your adapter initialization options
        Key: s3ObjectKey
    }, (err, s3Response) => {
        if (err) {
            console.error('Failed to read file from S3:', err);
            return;
        }

        // s3Response.Body is the raw image Buffer—Jimp can read this directly
        Jimp.read(s3Response.Body, function(err, image){
            if (err) {
                console.error('Jimp failed to parse image:', err);
                return;
            }

            // Process the image, then handle the resized buffer
            image.resize(600, Jimp.AUTO).quality(60).getBuffer(image.getMIME(), (err, resizedImageBuffer) => {
                if (err) {
                    console.error('Failed to generate resized buffer:', err);
                    return;
                }

                // Optional: Upload the resized image back to S3 (example)
                adapter.s3.putObject({
                    Bucket: options.bucket,
                    Key: `resized/${filesUploaded[0].filename}`, // New path for resized files
                    Body: resizedImageBuffer,
                    ContentType: filesUploaded[0].type
                }, (err) => {
                    err ? console.error('Failed to upload resized image:', err) : console.log('Resized image saved successfully!');
                });
            });
        });
    });
});

Key Details to Know:

  • extra.fd = S3 object key, not local path: Skipper-better-s3 stores files directly in S3, not your server's filesystem. The fd field maps to the object's key in the bucket, not a local file path.
  • Use the built-in S3 client: The adapter.s3 property is a pre-configured AWS SDK S3 client that matches your initial adapter settings—no need to set up a new one.
  • Jimp works with Buffers: s3Response.Body is the raw binary Buffer of your image, which Jimp accepts without extra conversion.
  • Add error handling everywhere: I added checks for every async step to catch issues early—this will save you hours of debugging later.

内容的提问来源于stack exchange,提问作者Eli Peters

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:18:25