2016-08-16 2 views
0

比較的簡単なAWS関数を実行してStripeにサブスクリプションを追加しています。私はちょうどそれを打った直後に、私はそれをヒットしない限り、30秒間に1件以上のリクエストがあった場合、Lambdaはリクエストを(APIゲートウェイ経由で)維持/削除できません(リクエストが完了する前にプロセスが終了しました)。

それは細かい動作します。もう一度PostManで実行しようとすると、失敗し、返されます。

{"errorMessage": "Process exited before completing request"} 

リクエストはAPIゲートウェイ経由で配信されます。

機能は、30代で構成されてタイムアウトと(再現性の@ 256Mを発行)〜ベース128MのRAM上で実行するように1300msを取るあります。

私は、私は2番目(同期)ミッションクリティカルなコンポーネントのためのラムダを使用するために私の決定を推測している...これはラムダを回避するように設計された、まさにだと思いました。

EDIT:

var stripe = require('stripe'); 

exports.handler = function (event, context, callback) { 
    var self = this; 
    stripe = stripe(getKey(event.stage, 'STRIPE_SECRET_KEY')); 
    self.createSubscription = createSubscription; 
    self.validPayload = validPayload; 

    console.log('event: ', event); 

    if (self.validPayload(event, context)) { 
     self.createSubscription(event, stripe, callback, context); 
    } 

    /** 
    * checks that the necessary payload has been received 
    * if YES: returns true and allows process to continue 
    * if NO: throws context.fail with useful error message(s) 
    * operating under custom error code naming convention of 
    * http code + 3 digit ULM error code 
    * @param event - from Lambda 
    * @param context - from Lambda 
    * @returns {boolean} - whether the payload contains the required data 
    */ 
    function validPayload (event, context) { 
     var errorResponse = { 
      status: 400, 
      errors: [] 
     }; 

     if (!event.billing_email) { 
      errorResponse.errors.push({ 
       code: 400001, 
       message: "No billing email provided." 
      }) 
     } 
     if (!event.plan) { 
      errorResponse.errors.push({ 
       code: 400002, 
       message: "No plan was selected." 
      }) 
     } 
     if (!event.token) { 
      errorResponse.errors.push({ 
       code: 400003, 
       message: "A valid credit card was not provided." 
      }) 
     } 

     if (!!errorResponse.errors.length) { 
      context.fail(JSON.stringify(errorResponse)); 
      return false; 
     } else { 
      return true; 
     } 
    } 

    /** 
    * Creates a new customer & subscription using stripe package method 
    * if success, executes callback with response data 
    * if fail, throws context.fail with useful error message(s) 
    * @param event - from Lambda 
    * @param stripe - probably not necessary... 
    * @param callback - from Lambda 
    * @param context - probably not necessary... 
    */ 
    function createSubscription (event, stripe, callback, context) { 
     stripe.customers.create({ 
      source: event.token, 
      plan: event.plan, 
      email: event.billing_email 
     }, function (err, customer) { 
      if (err) { 
       var errorResponse = { 
        status: 400, 
        errors: [] 
       }; 

       errorResponse.errors.push({ 
        code: 400004, 
        message: err.message 
       }); 

       console.error('Customer/Plan Creation Failed'); 
       callback(JSON.stringify(errorResponse)); 
      } else { 
       callback(null, { 
        status: 200, 
        customer: customer 
       }); 
      } 
     }); 

    } 

    function getKey (stage, keyId) { 
     var keys = { 
      STRIPE_SECRET_KEY: { 
       staging: 'sk_test_123456', 
       prod: 'sk_live_123456' 
      } 
     }; 

     if (stage === 'prod') { 
      return keys[keyId][stage]; 
     } else { 
      return keys[keyId]['staging']; 
     } 
    } 
}; 

EDIT 2:要求されたとして、ここでは機能コードですCloudWatchの掘り下げと、このエラーログを見つけました:TypeError: stripe is not a function at exports.handler (/var/task/exports.js:5:14)

+0

「可変」スコープと「暖かい」関数コンテナの問題のようですね。私はあなたに本当の答えを与えるためにいくつかのコードを見る必要があると思います。 – rowanu

+0

@rowanu:元の質問に追加。 –

答えて

4

@rowanuが正しいです、あなたの問題はこの行にありますstripe = stripe(getKey(event.stage, 'STRIPE_SECRET_KEY'));。 Lambdaは後続の要求を扱うために熱くなっているので、handler関数の外で宣言された変数は、新しい要求が入るたびに表示されます。これは簡単な修正であり、stripe変数を再定義しないでください。このようなものは、このトリックを行うでしょう:

var stripe = require('stripe'); 
var stripeInstance; // undefined on startup 

exports.handler = function (event, context, callback) { 
    // now define stripeInstance if its not already defined 
    if(!stripeInstance) { 
    stripeInstance = stripe(getKey(event.stage, 'STRIPE_SECRET_KEY')); 
    } 
    // now all functions will be able to use the same instance of stripe. 
    // This assumes the event.stage is always the same, if you need a new instance for every request then remove the if statement 
    // rename all references of stripe to stripeInstance 
    ... 
1

"プロセスが要求を完了する前に終了した" あなたの関数が終了したことを示していますコールバックを呼び出さずに。タイムアウトやスロットルには関係しません。

通常、これは適切なエラー処理がないコードパスから例外がスローされることを示します。

「ストライプはexports.handler(/var/task/exports.js:5:14)の関数ではありません」を処理または修正するだけで、適切なコールバックを呼び出す必要があります。

関連する問題