使用 Sails.js 的可选文件上传
Optional file uploads with Sails.js
是否可以让 Sails action 接受可选的文件上传 而不会 在请求后几秒钟吐出以下堆栈跟踪?
Upstream (file upload: `image`) emitted an error: { Error: EMAXBUFFER: An upstream (`NOOP_image`) timed out before it was plugged into a receiver. It was still unused after waiting 4500ms. You can configure this timeout by changing the `maxTimeToBuffer` option.
Note that this error might be occurring due to an earlier file upload that is finally timing out after an unrelated server error.
at Timeout.<anonymous> (/home/jarrod/workspace/cuckold/Cuckold-API/node_modules/skipper/lib/private/Upstream/Upstream.js:86:15)
at ontimeout (timers.js:498:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:290:5)
code: 'EMAXBUFFER',
message: 'EMAXBUFFER: An upstream (`NOOP_image`) timed out before it was plugged into a receiver. It was still unused after waiting 4500ms. You can configure this timeout by changing the `maxTimeToBuffer` option.\n\nNote that this error might be occurring due to an earlier file upload that is finally timing out after an unrelated server error.' }
为了完整起见,我使用自定义 Skipper 适配器将文件转储到 minio which I loosely based off the skipper-s3 适配器中,但我在使用默认的 store-files-in-.tmp-directory 适配器时也看到了相同的症状。
当在 HTTP 请求中提供时,下面的代码可以正常运行并接受并存储单个文件上传,但是如果 image
字段被省略,上面的内容将在所述请求后约 4.5 秒打印到控制台.
相关操作中最有趣的部分如下:
module.exports = {
friendlyName: 'Create or update a news article',
files: ['image'],
inputs: {
id: {
type: 'number',
description: 'ID of article to edit (omit for new articles)'
},
content: {
type: 'string',
description: 'Markdown-formatted content of news artcle',
required: true
},
image: {
type: 'ref'
},
},
exits: {
success: { }
},
fn: async function (inputs, exits) {
let id = inputs.id;
let article;
console.log('About to grab upload(s)')
let uploadedFiles = await (new Promise((resolve, reject) => {
this.req.file('image').upload({/* ... */}, (err, uploadedFiles) => {
console.log('Upload stuff callback', [err, uploadedFiles])
if (err) {
sails.log.error(`Unable to store uploads for news article`, err.stack)
return reject(new Error('Unable to store uploads')); // Return a vague message to the client
}
resolve(uploadedFiles)
});
}));
console.log('uploadedFiles', uploadedFiles)
if (uploadedFiles && uploadedFiles.length) {
uploadedFiles = uploadedFiles.map(f => f.fd)
} else {
uploadedFiles = null
}
// Do some database updating
return exits.success({ article });
}
};
如果 HTTP 请求中没有上传,那么 uploadedFiles
是一个空数组,其余的操作代码运行没有问题,但我不希望日志充满这种垃圾。
事实证明这真的很简单,只需从 npm 中拉入 sails-hook-uploads 模块并将原始问题中的 Promise-wrapped cruft 替换为这样的东西
let uploadedFiles = await sails.upload(inputs.image, {/* custom adapter config */});
似乎按预期工作,但如果在请求中提供 none,则不会记录上传未被及时拦截的警告。
Ration 示例应用程序导致此解决方案,here。
是否可以让 Sails action 接受可选的文件上传 而不会 在请求后几秒钟吐出以下堆栈跟踪?
Upstream (file upload: `image`) emitted an error: { Error: EMAXBUFFER: An upstream (`NOOP_image`) timed out before it was plugged into a receiver. It was still unused after waiting 4500ms. You can configure this timeout by changing the `maxTimeToBuffer` option.
Note that this error might be occurring due to an earlier file upload that is finally timing out after an unrelated server error.
at Timeout.<anonymous> (/home/jarrod/workspace/cuckold/Cuckold-API/node_modules/skipper/lib/private/Upstream/Upstream.js:86:15)
at ontimeout (timers.js:498:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:290:5)
code: 'EMAXBUFFER',
message: 'EMAXBUFFER: An upstream (`NOOP_image`) timed out before it was plugged into a receiver. It was still unused after waiting 4500ms. You can configure this timeout by changing the `maxTimeToBuffer` option.\n\nNote that this error might be occurring due to an earlier file upload that is finally timing out after an unrelated server error.' }
为了完整起见,我使用自定义 Skipper 适配器将文件转储到 minio which I loosely based off the skipper-s3 适配器中,但我在使用默认的 store-files-in-.tmp-directory 适配器时也看到了相同的症状。
当在 HTTP 请求中提供时,下面的代码可以正常运行并接受并存储单个文件上传,但是如果 image
字段被省略,上面的内容将在所述请求后约 4.5 秒打印到控制台.
相关操作中最有趣的部分如下:
module.exports = {
friendlyName: 'Create or update a news article',
files: ['image'],
inputs: {
id: {
type: 'number',
description: 'ID of article to edit (omit for new articles)'
},
content: {
type: 'string',
description: 'Markdown-formatted content of news artcle',
required: true
},
image: {
type: 'ref'
},
},
exits: {
success: { }
},
fn: async function (inputs, exits) {
let id = inputs.id;
let article;
console.log('About to grab upload(s)')
let uploadedFiles = await (new Promise((resolve, reject) => {
this.req.file('image').upload({/* ... */}, (err, uploadedFiles) => {
console.log('Upload stuff callback', [err, uploadedFiles])
if (err) {
sails.log.error(`Unable to store uploads for news article`, err.stack)
return reject(new Error('Unable to store uploads')); // Return a vague message to the client
}
resolve(uploadedFiles)
});
}));
console.log('uploadedFiles', uploadedFiles)
if (uploadedFiles && uploadedFiles.length) {
uploadedFiles = uploadedFiles.map(f => f.fd)
} else {
uploadedFiles = null
}
// Do some database updating
return exits.success({ article });
}
};
如果 HTTP 请求中没有上传,那么 uploadedFiles
是一个空数组,其余的操作代码运行没有问题,但我不希望日志充满这种垃圾。
事实证明这真的很简单,只需从 npm 中拉入 sails-hook-uploads 模块并将原始问题中的 Promise-wrapped cruft 替换为这样的东西
let uploadedFiles = await sails.upload(inputs.image, {/* custom adapter config */});
似乎按预期工作,但如果在请求中提供 none,则不会记录上传未被及时拦截的警告。
Ration 示例应用程序导致此解决方案,here。