2016-09-20 5 views
1

Hapi経由でAPIを提供するNodeJSアプリがあると、すべてのエラーをどのようにキャッチしてユーザーに伝えることができますか?致命的なエラーが発生した場合、私たちのサーバーにリクエストしたクライアントに500のエラーを送信できるようにする必要があります。Hapi NodeJSアプリケーションであらゆる致命的なエラーを検出し、クライアントに500エラーを送信するにはどうすればいいですか?

私たちはすべてのエラーを正しく捕捉するようにすべてを設定していたと思っていましたが、これは私たちの前を完全に過ぎました。

私はgithubからアプリを入手するために "git clone"を行い、次に "npm install"してから "npm run"しました。その後、私は数時間アプリで作業しました。それから私はラップトップを閉じて家に帰った。数時間後、私はラップトップを開き、私は仕事を続けたいと思っていました。しかし、外部データベースへの接続は古くなっていました。それは確かに理にかなっていますが、私たちのアプリはクライアントに問題を伝えていたはずです。私はカールを実行したときに代わり、:これは私たちのために受け入れられない

curl: (52) Empty reply from server 

curl "http://nefers-mbp.home:3000/profile/Company/31468" -X GET --header 'Accept: application/json' --header 'x-api-key: 2gt7Pt2LU194KKcNnXHRc564JU' 

を90秒後には、デフォルトのcURLタイムアウトを打ちます。私はすぐにエラーを送信したい。私はアプリを実行していた端末ウィンドウで

は、私は、データベース接続がエラーにつながる、古くなってしまっていたことを見た:

160920/111554.302, [ops], memory: 49Mb, uptime (seconds): 24285.523, load: 1.6513671875,2.2822265625,3.7041015625 
    { profile_type: 'Company', id: '31468' } 
    { method: 'select', 
    options: {}, 
    bindings: [ '2gt7Pt2LU194KKcNUxJU' ], 
    sql: 'select `user_id`, `action`, `permission` from `api_permissions` where `api_key` = ?' } 
    160920/11124.308, [ops], memory: 49Mb, uptime (seconds): 24315.529, load: 1.55640625,2.204105625,3.6259765625 
    Knex:Error Pool2 - Error: Pool.release(): Resource not member of pool 
    { Error: read ETIMEDOUT 
     at exports._errnoException (util.js:1026:11) 
     at TCP.onread (net.js:564:26) 
     -------------------- 
     at Protocol._enqueue (/Users/lsam/projects/mattermare/api/node_modules/mysql/lib/protocol/Protocol.js:141:48) 
     at Connection.query (/Users/lsam/projects/mattermare/api/node_modules/mysql/lib/Connection.js:201:25) 
     at /Users/lsam/projects/mattermare/api/node_modules/knex/lib/dialects/mysql/index.js:92:18 
     at tryCatcher (/Users/lsam/projects/mattermare/api/node_modules/bluebird/js/main/util.js:26:23) 
     at Promise._resolveFromResolver (/Users/lsam/projects/mattermare/api/node_modules/bluebird/js/main/promise.js:483:31) 
     at new Promise (/Users/lsam/projects/mattermare/api/node_modules/bluebird/js/main/promise.js:71:37) 
     at Client._query (/Users/lsam/projects/mattermare/api/node_modules/knex/lib/dialects/mysql/index.js:88:12) 
     at Client.query (/Users/lsam/projects/mattermare/api/node_modules/knex/lib/client.js:127:24) 
     at Runner.<anonymous> (/Users/lsam/projects/mattermare/api/node_modules/knex/lib/runner.js:116:24) 
     at Runner.tryCatcher (/Users/lsam/projects/mattermare/api/node_modules/bluebird/js/main/util.js:26:23) 
     at Runner.query (/Users/lsam/projects/mattermare/api/node_modules/bluebird/js/main/method.js:15:34) 
     at /Users/lsam/projects/mattermare/api/node_modules/knex/lib/runner.js:44:21 
     at /Users/lsam/projects/mattermare/api/node_modules/bluebird/js/main/using.js:176:30 
     at bound (domain.js:280:14) 
     at runBound (domain.js:293:12) 
     at tryCatcher (/Users/lsam/projects/mattermare/api/node_modules/bluebird/js/main/util.js:26:23) 
    code: 'ETIMEDOUT', 
    errno: 'ETIMEDOUT', 
    syscall: 'read', 
    fatal: true } 

このエラーは、コンソールでは、インスタントだったが、待機中のcURL要求には伝達されませんでした。これは私が修正したいものです。

私は役立つだろうNPMパッケージを探して行き、私はこれが見つかりました:だけはかなりのエラーメッセージを作ること

https://www.npmjs.com/package/hapi-error

どうやらを、。私たちの問題はより根本的です。私たちはこの致命的なエラーをキャッチしませんでした。

サーバは自動的に自分自身を修正したので、次に私はcURLを呼び出すときにアクティブなデータベース接続があったので、次回の呼び出しはうまくいった。

しかし、理由にかかわらずすべてのエラーをキャッチし、クライアントが妥当なメッセージを受け取るようにする必要があります。クライアントが単にタイムアウトしてしまう状況は許されません。

リバースプロキシ経由でApacheまたはNginxを使用した場合、タイムアウトが早くなる可能性がありますが、エラーが発生したときにNodeJSアプリケーション自身がエラーメッセージを送信するようにします発生しました。

我々はすでに、ほとんどのエラーをキャッチした "良い" を使用:として私たちが登録

https://www.npmjs.com/package/good

{ 
     "plugin": { 
     "register": "good", 
     "options": { 
      "opsInterval": 30000, 
      "reporters": [ 
      { 
       "reporter": "good-console", 
       "events": { 
        "log": "*", 
        "ops": "*", 
        "request": "*" 
       } 
      } 
      ] 
     } 
     } 
    } 

しかし、何らかの理由で、このエラーがキャッチされていませんでした。

すべてのエラーをキャッチして、待機中のクライアントに500エラーを送信する方法はありますか?

答えて

0

ルートコードを掲載できますか?コールバックや約束の終わりにreplyと呼んでいるようです。エラーが発生するとreplyが呼び出されません。

あなたはこのような何かをやっているかもしれない約束を使用している場合:

const myHandler = (req, reply) { 
    knex('users') 
    .first() 
    .where('id', req.params.id) 
    .then((user) => reply(formatUser(user)) 
} 

データベース接続は、サーバは永久に待機して呼び出されることはありません返信失敗した場合。あなたは約束チェーンすなわち​​の最後にキャッチを追加するには、それを修正することができたり、あなただけの約束を返すことができますし、HAPIは、これが満たしている場合、私は知らない500

const myHandler = (req, reply) { 
    const p = knex('users') 
    .first() 
    .where('id', req.params.id) 
    .then((user) => formatUser(user)) 

    reply(p); 
} 

に拒否された約束をオンにしますあなたの要求を自動的にキャッチすることができますが、Hapiの観点からはエラーはありませんでした。replyは決して呼び出されませんでした。

あなたはreplyを使用すると、ルートオプションでそれを行うことができますミリ秒数で呼び出されていない場合は503を返すために、ルートのタイムアウトを設定したい場合:

server.route({ 
    method: 'GET', 
    path: '/api/users/{userId}'', 
    config: { 
    timeout: { 
     server: 10000 
    } 
    }, 
    handler: myHandler 
}); 

または設定サーバー上の接続をセットアップするすべてのルートのタイムアウト:

server.connection({ port: 80, routes: { timeout: { server: 10000 } } }); 

タイムアウトを設定するには良い方法ですが、それはまだ一つの方法または別のハンドラがバックリプライコールを呼び出すことが保証されていることが不可欠です。そうすれば、あなたのルートはより早く失敗するでしょう。

+0

.then((user)=> reply(formatUser(user)) – LRK9

+0

プロミスチェーンを保存する: 'const p = dbStuff()。then(formatUser)'それから 'reply (p) '最後に。 – Gangstead

関連する問題