Zapier Cli - 未处理的错误

Zapier Cli - Unhandled error

我正在创建一个应用程序(目前)将一个文件作为输入并且returns它的散列( sha256).
只要用户使用文件作为输入,它就可以正常工作,但如果他输入其他内容(例如字符串),应用程序 无声地失败 (应用程序的堆栈跟踪日志,但 Zapier 没有显示任何特别内容) 和 returns 错误的散列

我的印象是错误可以通过我的代码处理并且堆栈非常混乱:

┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│     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))
    })
}

但是:我抓不到"Unhandled errors";我试过

process.on('unhandledRejection', (reason, p) => {
    console.log('Unhandled Rejection at:', p, 'reason:', reason);
    process.exit(1);
});

但我认为 Zapier 引擎阻止了这种技巧,因为它没有效果...

来自 Zapier Platform 团队的 David。没有魔法或花招,但看起来你让自己的生活变得更难了。许多 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)}
    })
};

我们还使对您的代码进行单元测试变得非常容易 - 如果它在本地运行,它也将在我们的服务器上运行。再一次,没有魔法!