2016-10-27 3 views
0

観測可能なストリームから例外をキャッチしないRxJに関する問題があります。RxJsがスローされたエラーをキャッチしない

私のコードは次のようになります。

const Rx = require('rx'); 
if (process.env.NODE_ENV === 'development') { 
    require('dotenv').load(); 
} 

const getTransactionsVerificationStatus = (params, models, retryLimit = process.env.CARD_VERIFICATION_ATTEMPTS_LIMIT) => { 
    const potCheckResult$ = models.pot().exists([params.userId, params.potId]); 

    const needsVerified$ = models.transaction() 
    .listUnverifiedCards([params.userId, params.potId]) 
    .map(card => { 
     return { 
     status: 'success', 
     data: { 
      card: { 
      id: card.id, 
      cardNumberMask: card.cardNumberMask, 
      attemptsRemaining: (retryLimit - card.attempts), 
      chargeDate: card.chargeDate, 
      expiry: card.expiry, 
      status: card.status 
      }, 
      requiresVerification: true 
     } 
     }; 
    }) 
    .take(1); 

    const verified$ = models.user() 
    .getDefaultCard([params.userId]) 
    .map(card => { 
     return { 
     status: 'success', 
     data: { 
      card: { 
      id: card.id, 
      cardNumberMask: card.cardNumberMask, 
      attemptsRemaining: (retryLimit - card.attempts), 
      chargeDate: card.chargeDate, 
      expiry: card.expiry, 
      status: card.status 
      }, 
      requiresVerification: false 
     } 
     }; 
    }) 
    .take(1); 

    const error$ = potCheckResult$ 
    .filter(x => x.len <= 0) 
    .map(() => { 
     return { 
     status: 'error', 
     message: ['Requested pot does not exist for current user'] 
     }; 
    }); 

    return Rx.Observable 
    .concat(error$, needsVerified$, verified$) 
    .take(1) 
    .catch(e => { 
     logger.warn(e); 

     return Rx.Observable.just(
     { 
      status: 'error', 
      type: 'array', 
      data: ['Something went wrong'] 
     } 
    ); 
    }); 
}; 

module.exports = getTransactionsVerificationStatus; 

は基本的に、3つの観測可能なストリームがconcat方法でマージされていることを、ここにあります。

これらのモデルのいずれかが例外をスローすると、catchメソッドでキャッチされないという問題があります。これらの例外をどのようにキャッチしますか?

ご協力いただければ幸いです!

編集:完全を期すために、ここで私は上記のコードで実行しているテストがある

const chai = require('chai'); 
chai.use(require('chai-json-schema')); 
const expect = chai.expect; 
const getTransactionsVerificationStatus = require('../get-transactions-verification-status'); 
const Rx = require('rx'); 

describe('Get Transactions Verification Logic', function() { 
    let models; 

    beforeEach(function() { 
    // Mock models 
    models = (params) => { 
     return { 
     pot:() => { 
      return { 
      exists:() => { 
       if(params.potExists) { 
       return Rx.Observable.just({ 
        len: params.potExists 
       }).toArray() 
       } else { 
       return Rx.Observable.just({ 
        len: 0 
       }); 
       } 
      } 
      } 
     }, 
     transaction:() => { 
      return { 
      listUnverifiedCards:() => { 
       if(params.error) { 
       throw new Error('This is an error!'); 
       } 
       if (params.unverifiedCards) { 
       return Rx.Observable.just({ 
        id: "unverified card", 
        cardNumberMask: 123456, 
        attempts: 0, 
        chargeDate: null, 
        expiry: 2016123, 
        status: 'UNVERIFIED' 
       }); 
       } else { 
       return Rx.Observable.empty() 
       } 
      } 
      }; 
     }, 
     user:() => { 
      return { 
      getDefaultCard:() => Rx.Observable.just(
       { 
       id: "verified card", 
       cardNumberMask: 123456, 
       attempts: 0, 
       chargeDate: null, 
       expiry: 2016123, 
       status: 'VERIFIED' 
       } 
      ) 
      }; 
     } 
     }; 
    }; 
    }); 

    it('should return a non-verified card if one has been used in a transaction', done => { 
    const params = { 
     userId: 123, 
     potId: 123 
    }; 

    const modelParams = { 
     potExists: 1, 
     unverifiedCards: true 
    }; 

    const response$ = getTransactionsVerificationStatus(
     params, 
     models(modelParams), 
     3 
    ); 

    response$.subscribe(json => { 
     expect(json).to.deep.equal({ 
     status: "success", 
     data: { 
      card: { 
      id: "unverified card", 
      cardNumberMask: 123456, 
      attemptsRemaining: 3, 
      chargeDate: null, 
      expiry: 2016123, 
      status: 'UNVERIFIED' 
      }, 
      "requiresVerification": true 
     } 
     }); 
     done(); 
    }); 
    }); 

    it('should return the active card if no transactions have used an unverified card', done => { 
    const params = { 
     userId: 123, 
     potId: 123 
    }; 

    const modelParams = { 
     potExists: 1, 
     unverifiedCards: false 
    }; 

    const response$ = getTransactionsVerificationStatus(
     params, 
     models(modelParams), 
     3 
    ); 

    response$.subscribe(json => { 
     expect(json).to.deep.equal({ 
     status: "success", 
     data: { 
      card: { 
      id: "verified card", 
      cardNumberMask: 123456, 
      attemptsRemaining: 3, 
      chargeDate: null, 
      expiry: 2016123, 
      status: 'VERIFIED' 
      }, 
      "requiresVerification": false 
     } 
     }); 
     done(); 
    }); 
    }); 

    it('should return an error message if the user does not have a pot with the id requested', done => { 
    const params = { 
     userId: 1, 
    }; 

    const modelParams = { 
     potExists: 0, 
     unverifiedCards: false, 
     verifiedCards: false 
    }; 

    const response$ = getTransactionsVerificationStatus(
     params, 
     models(modelParams), 
     3 
    ); 

    response$.subscribe(json => { 
     expect(json).to.deep.equal({ 
     status: 'error', 
     message: ['Requested pot does not exist for current user'] 
     }); 
     done(); 
    }); 
    }); 

    it('should handle all other errors', done => { 
    const params = { 
     userId: 1, 
    }; 

    const modelParams = { 
     potExists: 1, 
     unverifiedCards: true, 
     error: true 
    }; 

    const response$ = getTransactionsVerificationStatus(
     params, 
     models(modelParams), 
     3 
    ); 

    response$.subscribe(json => { 
     expect(json).to.deep.equal({ 
     status: 'error', 
     type: 'array', 
     data: ['Something went wrong'] 
     }); 
     done(); 
    }); 
    }); 
}); 

上記の主張のすべてがモデルにエラーがスローされます、最後の1を除い渡し、このエラーは拾わないし、それをクライアントになりますありません。

答えて

0

私はそれを理解しました。

問題はテストであり、getTransactionsVerificationStatus機能ではありませんでした。

問題は、私が投げていたエラーが観測可能なものから投げ出されたはずだったということでした。ここに私が更新したコードのビットがあります。

if (params.error) { 
    return Rx.Observable.create(() => { 
     throw new Error('Data error'); 
    }); 
    } 

これは、代わりに

if (params.error) { 
    throw new Error('Data error'); 
    } 

のうまくいけば、誰かが、これは便利見つけました。

0

連結しているストリームで、concatの後にtake(1)演算子があります。つまり、最初の値だけを聞きます。 takeオペレータは、暗黙的な購読解除を実行します。これは、最初の値がエラーではない場合、次のイベントが存在しないため、 'キャッチ'演算子がキャッチするエラーがないことを意味します。

第2に、あなたの例ではこのストリームを購読していません。これはあなたのコードの中でも実生活の中でも同じですか?ストリームを購読していない場合、ストリームは開始されません(通常、私が見ているもののためのコールドオブザーバブルで作業しているように)。

+0

このシナリオでは、値が1つだけ必要です。有効なカードのリスト、そうでないリスト、またはエラーのいずれかが必要です。エラーはこのインスタンスで最も重要な項目です。そのため、エラーは 'concat'メソッドの最初の項目です。 エラーはブラウザに表示されていることです。 この関数は、他のファイルでエクスポートおよびサブスクライブされています。 私は現在人為的にエラーをスローするためにmocha/chaiテストを使用しています。もし私がテストを含めると、それは役に立ちますか? –

+0

あなたはどこでエラーを投げますか?エラー$のマップ関数では、オブジェクトを返していてエラーを投げていません。これが問題だろうか? – KwintenP

+0

それは問題のように聞こえます。どのように私はマップ機能でそれをキャッチするだろうか? 私は、それがキャッチされるまでエラーが泡立つはずだったと思った。 –

関連する問題