我正在创建一个应用程序(暂时)将文件作为输入,返回其哈希(sha256)。
只要用户使用文件作为输入,它就可以正常工作,但是如果他放了其他东西(例如字符串),应用程序默默地失败(应用程序的日志中有一个堆栈跟踪,但是Zapier没有特别显示并返回错误的哈希。
我不会觉得我的代码可以处理错误,并且堆栈非常模糊:
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Log │ Unhandled error: Error: Error: Could not find the method to call: authentication.test │
│ │ What happened: │
│ │ Executing authentication.test with bundle │
│ │ Error: Could not find the method to call: authentication.test │
│ │ Error: Error: Could not find the method to call: authentication.test │
│ │ at execute (:censored:9:d1ba0cf2aa:/node_modules/zapier-platform-core/src/execute.js:83:11) │
│ │ at input (:censored:9:d1ba0cf2aa:/node_modules/zapier-platform-core/src/create-command-handler.js:26:12) │
│ │ at Object.beforeMiddleware.then.newInput (:censored:9:d1ba0cf2aa:/node_modules/zapier-platform-core/src/middleware.js:90:22) │
│ │ at bound (domain.js:280:14) │
│ │ at Object.runBound (domain.js:293:12) │
│ │ at Object.tryCatcher (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/util.js:16:23) │
│ │ at Promise._settlePromiseFromHandler (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/promise.js:512:31) │
│ │ at Promise._settlePromise (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/promise.js:569:18) │
│ │ at Promise._settlePromise0 (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/promise.js:614:10) │
│ │ at Promise._settlePromises (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/promise.js:693:18) │
│ │ at Async._drainQueue (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/async.js:133:16) │
│ │ at Async._drainQueues (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/async.js:143:10) │
│ │ at Immediate.Async.drainQueues (:censored:9:d1ba0cf2aa:/node_modules/bluebird/js/release/async.js:17:14) │
│ │ at runCallback (timers.js:672:20) │
│ │ at tryOnImmediate (timers.js:645:5) │
│ │ at processImmediate [as _immediateCallback] (timers.js:617:5) │
│ Version │ 1.0.7 │
│ Step │ │
│ Timestamp │ 2018-05-24T03:57:57-05:00 │
└───────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
我的代码基本上是"Files" Example App的副本,creates/uploadFile.js
文件替换为:
const request = require('request');
const crypto = require('crypto');
function hashStream(stream) {
const hash = crypto.createHash('sha256').setEncoding('hex');
return new Promise((resolve, reject) => {
stream.pipe(hash)
.on('finish', () => resolve(hash.read()))
.on('error', reject)
})
}
function hashFile(z, bundle) {
const fileStream = request(bundle.inputData.file);
return hashStream(fileStream).then((hash) => ({hash}));
};
module.exports = {
key: 'hashFile',
noun: 'File',
display: {
label: 'Hash File',
description: 'Performs a sha256 on file.'
},
operation: {
inputFields: [
{key: 'file', required: true, type: 'file', label: 'File'},
],
perform: hashFile,
sample: { filename: 'example.pdf' },
outputFields: [
{key: 'hash', type: 'string', label: 'Hash'}
],
}
};
更新:
我最终发现了我的错误:我假设request
函数在失败时会抛出错误。
因此hashFile
函数肯定会对错误页面进行哈希处理。
更改hashFile
功能解决了问题:
function hashFile(z, bundle) {
return new Promise((resolve, reject) => {
request(bundle.inputData.file)
.on('response', function ({statusCode}) {
if (200 === statusCode) {
hashStream(this).then((hash) => resolve({hash}));
} else {
reject(new Error(`Invalid status code ${statusCode}`));
}
})
.on('error', (err) => reject(err))
})
}
但是:我无法捕捉"未处理的错误" ;我试过
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at:', p, 'reason:', reason);
process.exit(1);
});
但我认为Zapier引擎会阻止这种技巧,因为它没有效果......
答案 0 :(得分:0)
David来自Zapier平台团队。没有任何魔法或诡计,但看起来你让自己的生活变得更加艰难。大多数zapier代码都不支持该事件模式(.on('x', function(){...)
)。相反,一切都已经使用了承诺。未处理的拒绝是指您未使用catch
子句处理的拒绝承诺。我们还提供了一个z.request
函数,它比使用request
软件包本身要好一点(尽管如果你愿意,这是允许的!)。查看有关making HTTP requests的文档部分。我们还有z.hash(algo, string)
方法。然后将您的代码更新为以下内容:
function hashFile(z, bundle) {
return z.request(bundle.inputData.file).then(response => {
if (response.code !== 200) {
throw new Error('something bad')
}
// might need to pull something else out of the response
// if response.content isn't the string contents of the file
return {hash: z.hash('sha256', response.content)}
})
};
我们也很容易对您的代码进行单元测试 - 如果它在本地运行,它也可以在我们的服务器上运行。再一次,没有魔力!