I just recovered a simple auth app built with ReactJS, redux-observable and RxJS.
I want to implement an error handler when the API backend send a response > 400
.
Actually, there is an epic that handle login process on LOGIN_REQUEST
event:
const apiLoginEpic = (action$, state$) =>
action$.pipe(
ofType(authConstant.LOGIN_REQUEST),
mergeMap(action => authService.loginApi(action.username, action.password)),
map(({ body }) => extractJwtPayload(body.token)),
map(authAction.login.apiSuccess),
logObservableErrorAndTriggerAction(authAction.login.apiFailure)
This epic just call a service, which is a simple fetch that refer to:
const fetchBackend = (path, options = {}, withCredentials = false) => {
fetch(`${process.env.REACT_APP_BACKEND_URL}${path}`, options)
.then(response =>
response.status < 400
? Promise.all([response, response.json()])
: Promise.reject(response)
)
.then(([response, body]) => ({
status: response.status,
headers: response.headers,
body,
}))
}
As you can see, when the response status is superior to 400
, it reject the promise. Then, in the epic (first code extract), the error is catch in logObservableErrorAndTriggerAction
function which is implemented as:
const logObservableErrorAndTriggerAction = action =>
catchError((response, source) =>
pipe(
tap(logger.error),
() => of(action(response)).pipe(merge(source))
)(response)
)
My problem is that I want to catch the response body in logObservableErrorAndTriggerAction
, which can be reusable.
Unfortunately, I don't have much knowledge about observalbes and RxJS.
When I try to use body of the response, it appears that it is a ReadableStream
. I tried a lot of things but I can't turn it into JSON :
{
body: ReadableStream,
bodyUsed: false,
headers: Headers {},
ok: false,
redirected: false,
status: 400,
statusText: "",
type: "cors",
url: "http://localhost/api/login"
}
Does anybody know how to manage my use case ?
Thank you very much, Sylvain