観測可能なストリームから例外をキャッチしない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を除い渡し、このエラーは拾わないし、それをクライアントになりますありません。
このシナリオでは、値が1つだけ必要です。有効なカードのリスト、そうでないリスト、またはエラーのいずれかが必要です。エラーはこのインスタンスで最も重要な項目です。そのため、エラーは 'concat'メソッドの最初の項目です。 エラーはブラウザに表示されていることです。 この関数は、他のファイルでエクスポートおよびサブスクライブされています。 私は現在人為的にエラーをスローするためにmocha/chaiテストを使用しています。もし私がテストを含めると、それは役に立ちますか? –
あなたはどこでエラーを投げますか?エラー$のマップ関数では、オブジェクトを返していてエラーを投げていません。これが問題だろうか? – KwintenP
それは問題のように聞こえます。どのように私はマップ機能でそれをキャッチするだろうか? 私は、それがキャッチされるまでエラーが泡立つはずだったと思った。 –