无法创建文件下载控制器:使用.pipe()遇TypeError问题求助
文件下载控制器.pipe()报错排查(TypeError: Cannot read property 'on' of undefined)
错误原因分析
你遇到的TypeError: Cannot read property 'on' of undefined,本质是filedown变量为undefined——也就是fileAdapter.read(URL_FILE)没有返回预期的可读流,核心问题出在这几个地方:
- 异步文件存在性检查失效,导致文件不存在时仍执行读取操作
- 手动拼接路径的方式存在兼容性问题,可能生成无效路径
- 对Sails框架的
exits响应类型理解错误,错误地将流pipe到exits.success
修正后的代码
const fs = require('fs'); const path = require('path'); module.exports = { inputs: { name_file: { type: "string", required: true } }, exits: { success: { description: "返回文件流", responseType: 'stream' // 声明返回类型为流 }, defaultError: { description: "捕获通用错误", responseType: "defaultError", }, fileNotFound: { description: "目标文件不存在", responseType: 'notFound' } }, fn: async function (inputs, exits) { const nameFile = inputs.name_file; // 用path模块拼接路径,自动适配系统分隔符 const filePath = path.join(process.cwd(), '.tmp', 'uploads', `${nameFile}.csv`); // 异步检查文件是否存在 try { await fs.promises.access(filePath, fs.constants.F_OK); } catch (err) { return exits.fileNotFound("文件不存在"); } const SkipperDisk = require('skipper-disk'); const fileAdapter = SkipperDisk(); const fileStream = fileAdapter.read(filePath); // 检查流是否正常生成 if (!fileStream) { return exits.defaultError("无法生成文件读取流"); } // 捕获流读取错误 fileStream.on('error', (err) => { return exits.defaultError(err.message); }); // 返回文件流给success exit,框架会自动处理响应 return exits.success(fileStream); } }
关键修正点说明
- 路径处理优化:使用
path.join替代手动拼接,避免Windows/Linux路径分隔符差异导致的无效路径问题 - 异步逻辑修正:用
fs.promises.access配合async/await确保文件存在后再执行读取,避免异步竞态问题 - Exit类型调整:将
success的responseType设为stream,符合Sails框架返回文件流的规范,无需手动调用pipe - 流的有效性检查:增加
fileStream的存在性判断,提前拦截读取失败的情况 - 错误处理完善:绑定流的
error事件,捕获读取过程中的异常并返回对应错误
内容的提问来源于stack exchange,提问作者RonaldGG Guzman
相关产品推荐
相关产品推荐

