0

我正在创建一个应用程序,它(现在)将文件作为输入返回其哈希值(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                                                                                                        │
└───────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

我的代码本质上是“文件”示例应用程序的副本,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 引擎阻止了这种技巧,因为它没有效果......

4

1 回答 1

0

大卫在这里,来自 Zapier 平台团队。没有任何魔法或技巧,但看起来你让自己的生活变得更加艰难。许多 zapier 代码不支持该事件模式 ( .on('x', function(){...))。相反,一切都已经使用了 Promise。未处理的拒绝是指您没有使用catch子句处理的被拒绝的承诺。我们还提供了z.request一个比使用request包本身更好的功能(尽管如果您愿意,这是允许的!)。查看有关发出 HTTP 请求的文档部分。我们也有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)}
    })
};

我们还让对代码进行单元测试变得非常容易——如果它在本地工作,它也可以在我们的服务器上工作。再次,没有魔法!

于 2018-05-24T20:03:40.067 回答