Skip to content

Instantly share code, notes, and snippets.

@Akiyamka
Last active April 25, 2018 11:33
Show Gist options
  • Select an option

  • Save Akiyamka/c5d4894c33060354b652229aeaf23b91 to your computer and use it in GitHub Desktop.

Select an option

Save Akiyamka/c5d4894c33060354b652229aeaf23b91 to your computer and use it in GitHub Desktop.
/**
* 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