fix(error handling): Simplified error handling
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
e4e41e6fe3
commit
b7aee9928e
@ -1,5 +1,4 @@
|
|||||||
import { of } from 'rxjs/observable/of';
|
import { of } from 'rxjs/observable/of';
|
||||||
import { _if } from 'rxjs/observable/if';
|
|
||||||
import { empty } from 'rxjs/observable/empty';
|
import { empty } from 'rxjs/observable/empty';
|
||||||
import {
|
import {
|
||||||
switchMap,
|
switchMap,
|
||||||
@ -29,8 +28,7 @@ import {
|
|||||||
openDonationModal,
|
openDonationModal,
|
||||||
shouldShowDonationSelector,
|
shouldShowDonationSelector,
|
||||||
updateComplete,
|
updateComplete,
|
||||||
updateFailed,
|
updateFailed
|
||||||
isOnlineSelector
|
|
||||||
} from '../../../redux/app';
|
} from '../../../redux/app';
|
||||||
|
|
||||||
import postUpdate$ from '../utils/postUpdate$';
|
import postUpdate$ from '../utils/postUpdate$';
|
||||||
@ -49,13 +47,7 @@ function postChallenge(update, username) {
|
|||||||
updateComplete()
|
updateComplete()
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
catchError(({ _body, _endpoint }) => {
|
catchError(() => of(updateFailed(update)))
|
||||||
let payload = _body;
|
|
||||||
if (typeof _body === 'string') {
|
|
||||||
payload = JSON.parse(_body);
|
|
||||||
}
|
|
||||||
return of(updateFailed({ endpoint: _endpoint, payload }));
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
return saveChallenge;
|
return saveChallenge;
|
||||||
}
|
}
|
||||||
@ -79,11 +71,7 @@ function submitModern(type, state) {
|
|||||||
endpoint: '/external/modern-challenge-completed',
|
endpoint: '/external/modern-challenge-completed',
|
||||||
payload: challengeInfo
|
payload: challengeInfo
|
||||||
};
|
};
|
||||||
return _if(
|
return postChallenge(update, username);
|
||||||
() => isOnlineSelector(state),
|
|
||||||
postChallenge(update, username),
|
|
||||||
of(updateFailed(update))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return empty();
|
return empty();
|
||||||
@ -106,12 +94,8 @@ function submitProject(type, state) {
|
|||||||
endpoint: '/external/project-completed',
|
endpoint: '/external/project-completed',
|
||||||
payload: challengeInfo
|
payload: challengeInfo
|
||||||
};
|
};
|
||||||
return _if(
|
return postChallenge(update, username).pipe(
|
||||||
() => isOnlineSelector(state),
|
concat(of(updateProjectFormValues({})))
|
||||||
postChallenge(update, username).pipe(
|
|
||||||
concat(of(updateProjectFormValues({})))
|
|
||||||
),
|
|
||||||
of(updateFailed(update))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,11 +114,7 @@ function submitBackendChallenge(type, state) {
|
|||||||
endpoint: '/external/backend-challenge-completed',
|
endpoint: '/external/backend-challenge-completed',
|
||||||
payload: challengeInfo
|
payload: challengeInfo
|
||||||
};
|
};
|
||||||
return _if(
|
return postChallenge(update, username);
|
||||||
() => isOnlineSelector(state),
|
|
||||||
postChallenge(update, username),
|
|
||||||
of(updateFailed(update))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return empty();
|
return empty();
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { _if } from 'rxjs/observable/if';
|
|
||||||
import { of } from 'rxjs/observable/of';
|
import { of } from 'rxjs/observable/of';
|
||||||
import { ofType } from 'redux-observable';
|
import { ofType } from 'redux-observable';
|
||||||
|
|
||||||
@ -8,8 +7,7 @@ import {
|
|||||||
isSignedInSelector,
|
isSignedInSelector,
|
||||||
currentChallengeIdSelector,
|
currentChallengeIdSelector,
|
||||||
updateComplete,
|
updateComplete,
|
||||||
updateFailed,
|
updateFailed
|
||||||
isOnlineSelector
|
|
||||||
} from '../../../redux/app';
|
} from '../../../redux/app';
|
||||||
import postUpdate$ from '../utils/postUpdate$';
|
import postUpdate$ from '../utils/postUpdate$';
|
||||||
|
|
||||||
@ -25,18 +23,10 @@ function currentChallengeEpic(action$, { getState }) {
|
|||||||
currentChallengeId: payload
|
currentChallengeId: payload
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return _if(
|
return postUpdate$(update).pipe(
|
||||||
() => isOnlineSelector(getState()),
|
mapTo(updateComplete()),
|
||||||
postUpdate$(update).pipe(mapTo(updateComplete())),
|
catchError(() => of(updateFailed(update)))
|
||||||
of(updateFailed(update))
|
);
|
||||||
);
|
|
||||||
}),
|
|
||||||
catchError(({ _body, _endpoint }) => {
|
|
||||||
let payload = _body;
|
|
||||||
if (typeof _body === 'string') {
|
|
||||||
payload = JSON.parse(_body);
|
|
||||||
}
|
|
||||||
return of(updateFailed({ endpoint: _endpoint, payload }));
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ import debugFactory from 'debug';
|
|||||||
import { Observable, noop } from 'rxjs';
|
import { Observable, noop } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { isGoodXHRStatus } from './';
|
||||||
|
|
||||||
const debug = debugFactory('fcc:ajax$');
|
const debug = debugFactory('fcc:ajax$');
|
||||||
const root = typeof window !== 'undefined' ? window : {};
|
const root = typeof window !== 'undefined' ? window : {};
|
||||||
|
|
||||||
@ -67,14 +69,19 @@ function getCORSRequest() {
|
|||||||
|
|
||||||
function parseXhrResponse(responseType, xhr) {
|
function parseXhrResponse(responseType, xhr) {
|
||||||
switch (responseType) {
|
switch (responseType) {
|
||||||
case 'json':
|
case 'json': {
|
||||||
if ('response' in xhr) {
|
if (isGoodXHRStatus(xhr.status)) {
|
||||||
return xhr.responseType
|
if ('response' in xhr) {
|
||||||
? xhr.response
|
return xhr.responseType
|
||||||
: JSON.parse(xhr.response || xhr.responseText || 'null');
|
? xhr.response
|
||||||
|
: JSON.parse(xhr.response || xhr.responseText || 'null');
|
||||||
|
} else {
|
||||||
|
return JSON.parse(xhr.responseText || 'null');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return JSON.parse(xhr.responseText || 'null');
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case 'xml':
|
case 'xml':
|
||||||
return xhr.responseXML;
|
return xhr.responseXML;
|
||||||
case 'text':
|
case 'text':
|
||||||
@ -293,7 +300,7 @@ export function postJSON$(url, body) {
|
|||||||
Accept: 'application/json'
|
Accept: 'application/json'
|
||||||
},
|
},
|
||||||
normalizeError: (e, xhr) => parseXhrResponse('json', xhr)
|
normalizeError: (e, xhr) => parseXhrResponse('json', xhr)
|
||||||
}).pipe(map(({ response }) => response));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an observable sequence from an Ajax GET Request with the body.
|
// Creates an observable sequence from an Ajax GET Request with the body.
|
||||||
@ -318,5 +325,5 @@ export function getJSON$(url) {
|
|||||||
Accept: 'application/json'
|
Accept: 'application/json'
|
||||||
},
|
},
|
||||||
normalizeError: (e, xhr) => parseXhrResponse('json', xhr)
|
normalizeError: (e, xhr) => parseXhrResponse('json', xhr)
|
||||||
}).map(({ response }) => response);
|
}).pipe(map(({ response }) => response));
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,8 @@ const guideBase = 'https://guide.freecodecamp.org/certifications';
|
|||||||
export function createGuideUrl(slug = '') {
|
export function createGuideUrl(slug = '') {
|
||||||
return guideBase + slug;
|
return guideBase + slug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isGoodXHRStatus(status) {
|
||||||
|
const statusInt = parseInt(status, 10);
|
||||||
|
return statusInt >= 200 && statusInt < 400;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user