Last active
April 25, 2018 11:33
-
-
Save Akiyamka/c5d4894c33060354b652229aeaf23b91 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * NEAT FETCH | |
| * | |
| * In the process of communicating with the server, | |
| * we have a lot of places where there will be an error. | |
| * | |
| * The main purpose of this code is to unify the response even in case of an error. | |
| * If we know exactly what the object function will return, | |
| * the code will be easier to debug and work more reliably. | |
| * | |
| * Allocated four error handling layer: | |
| * 1. Network error - CORS error, lost connection, client side block (Adblock) | |
| * 2. Server-side errors - response not in range 200-299 | |
| * 3. Client-side errors - basicly, parse server response crush | |
| * 4. Syntetick errors - backend validation messages | |
| */ | |
| class APIResponse { | |
| constructor() { | |
| this.ok = true; | |
| this.message = undefined; | |
| this.privateData = null; | |
| } | |
| set error(errorData) { | |
| this.ok = false; | |
| this.message = errorData || 'Unknown error'; | |
| } | |
| /** | |
| * Four layer check - Syntetick errors | |
| * Possible structures: | |
| * @param {string} responseObject.count | |
| * @param {Array} responseObject.data | |
| * --- OR --- | |
| * @param {Object} responseObject - constants / info / me | |
| * --- OR --- | |
| * @param {Array} responseObject.error | |
| */ | |
| set data(responseObject) { | |
| if (responseObject.success === false) { | |
| console.debug('Syntetick backend error:', responseObject); | |
| this.error = responseObject.message; | |
| } else if (responseObject.error) { | |
| console.debug('Syntetick backend error:', responseObject); | |
| this.error = responseObject.error; | |
| } else { | |
| this.privateData = responseObject; | |
| } | |
| } | |
| get data() { | |
| return this.ok | |
| ? { | |
| data: { ...this.privateData }, | |
| } | |
| : { | |
| data: { error: this.message }, | |
| }; | |
| } | |
| /** Response parser */ | |
| async ejectData(data) { | |
| const reponseString = await data.text(); | |
| try { | |
| const responseJSON = JSON.parse(reponseString); | |
| return { | |
| ok: true, | |
| result: responseJSON, | |
| }; | |
| } catch (error) { | |
| console.debug('Parse response error:', error); | |
| return { | |
| ok: false, | |
| result: error.message || 'Cannot parse response', | |
| }; | |
| } | |
| } | |
| } | |
| export async function neatFecth(...request) { | |
| const apiResponse = new APIResponse(); | |
| /* First layer check - Network errors */ | |
| try { | |
| const response = await fetch.apply(this, request); | |
| /* Second layer check - Server-side errors */ | |
| if (response.ok) { | |
| /* Thrid layer check - Client-side errors */ | |
| const parsedResult = await apiResponse.ejectData(response.blob()); | |
| apiResponse[parsedResult.ok ? 'data' : 'error'] = parsedResult.result; | |
| } else { | |
| console.debug('Reponse not ok:', response); | |
| apiResponse.error = response.statusText; | |
| } | |
| } catch (error) { | |
| console.debug('Fetch error:', error); | |
| apiResponse.error = error.message; | |
| } | |
| return apiResponse; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment