How to solve "Unhandled promise rejection" error? - javascript

I was trying to reuse the existing and working function in my azure timer trigger function. But I encountered an error below.
(node:66694) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block or by rejecting a promise which was not handled with .catch().
I already tried to wrap try-catch the setTimeout but still, the same error occurred.
here is my code:
export const request = async (
reuqestOptions: Options,
waitTime?: number
): Promise<Response> => {
return new Promise((resolve) => {
setTimeout(() => {
// ... more code here
const req = https.request(options, (res) => {
// ... more code here
res.on('end', async () => {
// ... more code here
resolve({
body: result,
statusCode: res.statusCode,
headers: res.headers,
})
})
})
req.on('error', (e) => {
console.log(e.message)
})
req.end()
}, 3000 || 0)
})
}
here is how I call request:
export const requestToken = async (
usernmae: string,
password: string
): Promise<any> => {
try {
const response = await request({
method: 'POST',
// ...more code here
})
if (response.statusCode !== 200) {
throw new Error(JSON.stringify(response.body))
}
return response
} catch (error) {
throw new Error('request token is invalid')
}
}

So you have two places where you need to catch the error, or say, put a try block. First one would be the place where you make the http request. The other one would be the place where you actually call this function (which returns the promise).
wrapping the setTimeout in a try catch block will have no consequence as by the time the callback is fired, the try block would have ended.
For first case, you are registering an "error" callback, so thats all good. You just need to handle the second case (Promise).
export const request = async (
reuqestOptions: Options,
waitTime?: number
): Promise<Response> => {
return new Promise((resolve) => {
setTimeout(() => {
// ... more code here
const req = https.request(options, (res) => {
// ... more code here
res.on('end', async () => {
// ... more code here
resolve({
body: result,
statusCode: res.statusCode,
headers: res.headers,
})
})
})
req.on('error', (e) => {
console.log(e.message)
})
req.end()
}, 3000 || 0)
}).catch(err){
//...handle your error here
}
}

Related

Managing fetch errors with catch() doesn't work [duplicate]

Here's what I have going:
import 'whatwg-fetch';
function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
throw(error);
})
});
};
}
function status(res) {
if (!res.ok) {
return Promise.reject()
}
return res;
}
EDIT: The promise doesn't get rejected, that's what I'm trying to figure out.
I'm using this fetch polyfill in Redux with redux-promise-middleware.
Fetch promises only reject with a TypeError when a network error occurs. Since 4xx and 5xx responses aren't network errors, there's nothing to catch. You'll need to throw an error yourself to use Promise#catch.
A fetch Response conveniently supplies an ok , which tells you whether the request succeeded. Something like this should do the trick:
fetch(url).then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Something went wrong');
})
.then((responseJson) => {
// Do something with the response
})
.catch((error) => {
console.log(error)
});
The following login with username and password example shows how to:
Check response.ok
reject if not OK, instead of throw an error
Further process any error hints from server, e.g. validation issues
login() {
const url = "https://example.com/api/users/login";
const headers = {
Accept: "application/json",
"Content-Type": "application/json",
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify({
email: this.username,
password: this.password,
}),
})
.then((response) => {
// 1. check response.ok
if (response.ok) {
return response.json();
}
return Promise.reject(response); // 2. reject instead of throw
})
.then((json) => {
// all good, token is ready
this.store.commit("token", json.access_token);
})
.catch((response) => {
console.log(response.status, response.statusText);
// 3. get error messages, if any
response.json().then((json: any) => {
console.log(json);
})
});
},
Thanks for the help everyone, rejecting the promise in .catch() solved my issue:
export function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
return Promise.reject()
})
});
};
}
function status(res) {
if (!res.ok) {
throw new Error(res.statusText);
}
return res;
}
For me,
fny answers really got it all. since fetch is not throwing error, we need to throw/handle the error ourselves.
Posting my solution with async/await. I think it's more strait forward and readable
Solution 1: Not throwing an error, handle the error ourselves
async _fetch(request) {
const fetchResult = await fetch(request); //Making the req
const result = await fetchResult.json(); // parsing the response
if (fetchResult.ok) {
return result; // return success object
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
const error = new Error();
error.info = responseError;
return (error);
}
Here if we getting an error, we are building an error object, plain JS object and returning it, the con is that we need to handle it outside.
How to use:
const userSaved = await apiCall(data); // calling fetch
if (userSaved instanceof Error) {
debug.log('Failed saving user', userSaved); // handle error
return;
}
debug.log('Success saving user', userSaved); // handle success
Solution 2: Throwing an error, using try/catch
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
let error = new Error();
error = { ...error, ...responseError };
throw (error);
}
Here we are throwing and error that we created, since Error ctor approve only string, Im creating the plain Error js object, and the use will be:
try {
const userSaved = await apiCall(data); // calling fetch
debug.log('Success saving user', userSaved); // handle success
} catch (e) {
debug.log('Failed saving user', userSaved); // handle error
}
Solution 3: Using customer error
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
throw new ClassError(result.message, result.data, result.code);
}
And:
class ClassError extends Error {
constructor(message = 'Something went wrong', data = '', code = '') {
super();
this.message = message;
this.data = data;
this.code = code;
}
}
Hope it helped.
2021 TypeScript Answer
What I do is write a fetch wrapper that takes a generic and if the response is ok it will auto .json() and type assert the result, otherwise the wrapper throws the response
export const fetcher = async <T>(input: RequestInfo, init?: RequestInit) => {
const response = await fetch(input, init);
if (!response.ok) {
throw response;
}
return response.json() as Promise<T>;
};
and then I'll catch errors and check if they are an instanceof Response. That way TypeScript knows that error has Response properties such as status statusText body headers etc. and I can apply a custom message for each 4xx 5xx status code.
try {
return await fetcher<LoginResponse>("http://localhost:8080/login", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ email: "user#example.com", password: "passw0rd" }),
});
} catch (error) {
if (error instanceof Response) {
switch (error.status) {
case 401:
throw new Error("Invalid login credentials");
/* ... */
default:
throw new Error(`Unknown server error occured: ${error.statusText}`);
}
}
throw new Error(`Something went wrong: ${error.message || error}`);
}
and if something like a network error occurs it can be caught outside of the instanceof Response check with a more generic message i.e.
throw new Error(`Something went wrong: ${error.message || error}`);
The answer by #fny (the accepted answer) didn't work for me. The throw new Error() wasn't getting picked up by the .catch. My solution was to wrap the fetch with a function that builds a new promise:
function my_fetch(url, args) {
return new Promise((resolve, reject) => {
fetch(url, args)
.then((response) => {
response.text().then((body) => {
if (response.ok) {
resolve(body)
} else {
reject(body)
}
})
})
.catch((error) => { reject(error) })
})
}
Now every error and non-ok return will be picked up by the .catch method:
my_fetch(url, args)
.then((response) => {
// Do something with the response
})
.catch((error) => {
// Do something with the error
})
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
fetch("https://example.com/api/users")
.then(handleErrors)
.then(response => console.log("ok") )
.catch(error => console.log(error) );
I wasn't satisfied with any of the suggested solutions, so I played a bit with Fetch API to find a way to handle both success responses and error responses.
Plan was to get {status: XXX, message: 'a message'} format as a result in both cases.
Note: Success response can contain an empty body. In that case we fallback and use Response.status and Response.statusText to populate resulting response object.
fetch(url)
.then(handleResponse)
.then((responseJson) => {
// Do something with the response
})
.catch((error) => {
console.log(error)
});
export const handleResponse = (res) => {
if (!res.ok) {
return res
.text()
.then(result => JSON.parse(result))
.then(result => Promise.reject({ status: result.status, message: result.message }));
}
return res
.json()
.then(result => Promise.resolve(result))
.catch(() => Promise.resolve({ status: res.status, message: res.statusText }));
};
I just checked the status of the response object:
$promise.then( function successCallback(response) {
console.log(response);
if (response.status === 200) { ... }
});
Hope this helps for me throw Error is not working
function handleErrors(response) {
if (!response.ok) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject({
status: response.status,
statusText: response.statusText,
});
}, 0);
});
}
return response.json();
}
function clickHandler(event) {
const textInput = input.value;
let output;
fetch(`${URL}${encodeURI(textInput)}`)
.then(handleErrors)
.then((json) => {
output = json.contents.translated;
console.log(output);
outputDiv.innerHTML = "<p>" + output + "</p>";
})
.catch((error) => alert(error.statusText));
}
Another (shorter) version that resonates with most answers:
fetch(url)
.then(response => response.ok ? response.json() : Promise.reject(response))
.then(json => doStuff(json)) //all good
//next line is optional
.catch(response => handleError(response)) //handle error

How to properly handle reject in Promises

We have this function in our code that is used to log in a user
const userLogin = loginData => {
return new Promise(async (resolve, reject) => {
try {
const res = await auth.post("/login", loginData);
resolve(res);
} catch (error) {
reject(error);
}
});
};
// Calling function
const loginSubmit = async values => {
try {
const res = await userLogin(values);
console.info(res);
} catch (error) {
console.error("Catch: ", error);
}
};
But from this stackoverflow answer, try-catch blocks are redundant in Promises. I wanted to try and clean this code, so I changed the code above into:
const userLogin = loginData => {
return new Promise(async (resolve, reject) => {
const res = await auth.post("/login", loginData);
if (res.status !== 201) {
reject(new Error("Error"));
}
resolve(res);
});
};
However, when I tried to login with incorrect credentials, the console logs an Uncaught (in promise) Error: Request failed with status code 400
I'm not really familiar with creating my own promises, so I don't know how to do this properly.
Couple of problems in your code:
You are unnecessarily creating a promise; auth.post(..) already returns a promise, so you don't need to create a promise yourself and wrap auth.post(...) inside a promise constructor.
Another problem in your code is that executor function (function passed to the promise constructor) is marked as async; it should not be an async function.
Your function could be re-written as:
const userLogin = async (loginData) => {
const res = await auth.post("/login", loginData);
if (res.status !== 201) {
throw new Error("Error"));
}
return res;
};
You could also re-write your function as:
const userLogin = async (loginData) => {
return auth.post("/login", loginData);
};
Don't forget to use the catch in the code that calls this function.
You might want to read the following article to understand whether you need the try-catch block: await vs return vs return await
I think that in your case since you call to async function inside the constructor of the promise you need to use try catch.
The answer you referred is correct as long as the error happened while you are in the constructor (i.e. the Promise object is in the making), however in your case the rejection of the auth function happens long after the Promise was constructed and therefore it is not rejecting it.
BTW - You don't have to await in the promise. You may do the following:
const userLogin = loginData => {
return new Promise(async (resolve, reject) => {
const prom = auth.post("/login", loginData)
.then((res) => {
if (res.status !== 201) {
reject(new Error("Error"));
}
resolve(res);
});
resolve(prom);
});
};
Since you resolve the async auth call, any rejection by the auth call will be reflect as a rejection from you function

How to throw out of then-catch block?

I am currently figuring out how to throw an Exception out of a then catch block. I want to get into the catch that is inside the errorHandler() function.
const errorHandler = function () {
try {
thisFunctionReturnsAnError().then(response => {
console.log(response);
});
} catch (e) {
console.log(e); //How to trigger this?
}
};
const thisFunctionReturnsAnError = function () {
return3()
.then(value => {
throw new Error('This is the error message.');
})
.catch(err => {
//return Promise.reject('this will get rejected');
throw err;
//this one should somehow got to the catch that is located in the errorHandler() function. How to do this?
//I know that this 'err' will be in the next catch block that is written here. This is not what i want.
});
};
const return3 = async function () {
return 3;
};
errorHandler();
I searched a while on stackoverflow but nothing helped me. I am sure that this question got asked often but I could not find the answer, sorry for that.
EDIT:
added here another version of the code but it still does not work
const errorHandler = async function () {
try {
thisFunctionReturnsAnError()
.then(response => console.log(response))
.catch(err => console.log(err));
} catch (e) {
//console.log(e); //How to trigger this?
}
};
const thisFunctionReturnsAnError = function () {
return3()
.then(value => {
throw new Error('This is the error message.');
})
.catch(err => {
return Promise.reject(`Message is: ${err}`);
});
};
const return3 = async function () {
return 3;
};
errorHandler();
I will get the following error message:
Uncaught (in promise) Message is: Error: This is the error message.
Your code can't be executed, because "thisFunctionReturnsAnError" is not returning an Promise. That means that you can't call "then" on the return value.
thisFunctionReturnsAnError().then(response => { // will not work
Why not always use a promise?
const errorHandler = function () {
thisFunctionReturnsAnError()
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log('errorHandler: Handle the error.');
});
};
const thisFunctionReturnsAnError = function () {
return return_Three()
.then((value) => {
throw new Error('This is the error message.');
})
.catch((err) => {
//return Promise.reject('this will get rejected');
throw err;
//this one should somehow got to the catch that is located in the errorHandler() function. How to do this?
//I know that this 'err' will be in the next catch block that is written here. This is not what i want.
});
};
const return_Three = async function () {
return 3;
};
errorHandler();
/*****JUST ANOTHER SYNTAX*******/
const secondErrorHandler = async function () {
try {
await thisFunctionReturnsAnError();
} catch (error) {
console.log('secondErrorHandler: Handle the error.');
}
};
secondErrorHandler();
You cannot handle promise rejections with synchronous try/catch. Don't use it, use the promise .catch() method like in your thisFunctionReturnsAnError function.
You can handle promise rejections with try/catch when using async/await syntax (which you already do, albeit unnecessarily, in return3):
async function errorHandler() { /*
^^^^^ */
try {
const response = await thisFunctionReturnsAnError();
// ^^^^^
console.log(response);
} catch (e) {
console.log(e); // works
}
}

nested promise reject behaviour

i've some doubt on promise:
this is my api functions using axios:
const _get = (url: string) => axios
.get(url)
.then((response: { data: responseData }) => {
if (response) {
console.log(response)
const { data, status, message } = response.data;
if (status) {
return data
} else {
throw new Error(message);
}
}
})
//notification is an antd component to show a toast with the error
.catch((error: Error) => notification.error({ message: 'Error', description: error.message }));
export const doStuff = (id: number) =>_get('/api/do/${id}');
When i call the api in case of error the then() is called
const callDoStuff = (id: number) => {
doStuff(id).then(() => {
//called also if doStuff catch() is resolved
notification.success({ message: 'Success', description: 'Template deleted!' });
});
};
so in catch block if i return something is considered resolved and so the outer function then() is called? in this case the only way is to keep the propagation of the error throwing an exception in the catch?
Thanks
possible soulution:
const _get = (url: string) => axios
.get(url)
.then((response: { data: responseData }) => {
if (response) {
console.log(response)
const { data, status, message } = response.data;
if (status) {
return data
} else {
throw new Error(message);
}
}
})
using specific catcher for then() error
const callDoStuff = (id: number) => {
doStuff(id)
.then((response) => {// success handler}, e=>{// specific error thrown by the inner then })})
.catch(e=>{//axios error })
using generic catcher for errors
const callDoStuff = (id: number) => {
doStuff(id)
.then((response) => { //success handler })
.catch(e=>{ // generic error handler })
so in catch block if i return something is considered resolved and so the outer function then() is called?
Yes.
in this case the only way is to keep the propagation of the error throwing an exception in the catch?
I would suggest not to put the .catch() inside _get. Instead, write
function callDoStuff(id: number) {
doStuff(id).then(() => {
notification.success({ message: 'Success', description: 'Template deleted!' });
}, (error: Error) => {
notification.error({ message: 'Error', description: error.message })
});
}

Fetch: reject promise and catch the error if status is not OK?

Here's what I have going:
import 'whatwg-fetch';
function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
throw(error);
})
});
};
}
function status(res) {
if (!res.ok) {
return Promise.reject()
}
return res;
}
EDIT: The promise doesn't get rejected, that's what I'm trying to figure out.
I'm using this fetch polyfill in Redux with redux-promise-middleware.
Fetch promises only reject with a TypeError when a network error occurs. Since 4xx and 5xx responses aren't network errors, there's nothing to catch. You'll need to throw an error yourself to use Promise#catch.
A fetch Response conveniently supplies an ok , which tells you whether the request succeeded. Something like this should do the trick:
fetch(url).then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Something went wrong');
})
.then((responseJson) => {
// Do something with the response
})
.catch((error) => {
console.log(error)
});
The following login with username and password example shows how to:
Check response.ok
reject if not OK, instead of throw an error
Further process any error hints from server, e.g. validation issues
login() {
const url = "https://example.com/api/users/login";
const headers = {
Accept: "application/json",
"Content-Type": "application/json",
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify({
email: this.username,
password: this.password,
}),
})
.then((response) => {
// 1. check response.ok
if (response.ok) {
return response.json();
}
return Promise.reject(response); // 2. reject instead of throw
})
.then((json) => {
// all good, token is ready
this.store.commit("token", json.access_token);
})
.catch((response) => {
console.log(response.status, response.statusText);
// 3. get error messages, if any
response.json().then((json: any) => {
console.log(json);
})
});
},
Thanks for the help everyone, rejecting the promise in .catch() solved my issue:
export function fetchVehicle(id) {
return dispatch => {
return dispatch({
type: 'FETCH_VEHICLE',
payload: fetch(`http://swapi.co/api/vehicles/${id}/`)
.then(status)
.then(res => res.json())
.catch(error => {
return Promise.reject()
})
});
};
}
function status(res) {
if (!res.ok) {
throw new Error(res.statusText);
}
return res;
}
For me,
fny answers really got it all. since fetch is not throwing error, we need to throw/handle the error ourselves.
Posting my solution with async/await. I think it's more strait forward and readable
Solution 1: Not throwing an error, handle the error ourselves
async _fetch(request) {
const fetchResult = await fetch(request); //Making the req
const result = await fetchResult.json(); // parsing the response
if (fetchResult.ok) {
return result; // return success object
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
const error = new Error();
error.info = responseError;
return (error);
}
Here if we getting an error, we are building an error object, plain JS object and returning it, the con is that we need to handle it outside.
How to use:
const userSaved = await apiCall(data); // calling fetch
if (userSaved instanceof Error) {
debug.log('Failed saving user', userSaved); // handle error
return;
}
debug.log('Success saving user', userSaved); // handle success
Solution 2: Throwing an error, using try/catch
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
const responseError = {
type: 'Error',
message: result.message || 'Something went wrong',
data: result.data || '',
code: result.code || '',
};
let error = new Error();
error = { ...error, ...responseError };
throw (error);
}
Here we are throwing and error that we created, since Error ctor approve only string, Im creating the plain Error js object, and the use will be:
try {
const userSaved = await apiCall(data); // calling fetch
debug.log('Success saving user', userSaved); // handle success
} catch (e) {
debug.log('Failed saving user', userSaved); // handle error
}
Solution 3: Using customer error
async _fetch(request) {
const fetchResult = await fetch(request);
const result = await fetchResult.json();
if (fetchResult.ok) {
return result;
}
throw new ClassError(result.message, result.data, result.code);
}
And:
class ClassError extends Error {
constructor(message = 'Something went wrong', data = '', code = '') {
super();
this.message = message;
this.data = data;
this.code = code;
}
}
Hope it helped.
2021 TypeScript Answer
What I do is write a fetch wrapper that takes a generic and if the response is ok it will auto .json() and type assert the result, otherwise the wrapper throws the response
export const fetcher = async <T>(input: RequestInfo, init?: RequestInit) => {
const response = await fetch(input, init);
if (!response.ok) {
throw response;
}
return response.json() as Promise<T>;
};
and then I'll catch errors and check if they are an instanceof Response. That way TypeScript knows that error has Response properties such as status statusText body headers etc. and I can apply a custom message for each 4xx 5xx status code.
try {
return await fetcher<LoginResponse>("http://localhost:8080/login", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({ email: "user#example.com", password: "passw0rd" }),
});
} catch (error) {
if (error instanceof Response) {
switch (error.status) {
case 401:
throw new Error("Invalid login credentials");
/* ... */
default:
throw new Error(`Unknown server error occured: ${error.statusText}`);
}
}
throw new Error(`Something went wrong: ${error.message || error}`);
}
and if something like a network error occurs it can be caught outside of the instanceof Response check with a more generic message i.e.
throw new Error(`Something went wrong: ${error.message || error}`);
The answer by #fny (the accepted answer) didn't work for me. The throw new Error() wasn't getting picked up by the .catch. My solution was to wrap the fetch with a function that builds a new promise:
function my_fetch(url, args) {
return new Promise((resolve, reject) => {
fetch(url, args)
.then((response) => {
response.text().then((body) => {
if (response.ok) {
resolve(body)
} else {
reject(body)
}
})
})
.catch((error) => { reject(error) })
})
}
Now every error and non-ok return will be picked up by the .catch method:
my_fetch(url, args)
.then((response) => {
// Do something with the response
})
.catch((error) => {
// Do something with the error
})
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
fetch("https://example.com/api/users")
.then(handleErrors)
.then(response => console.log("ok") )
.catch(error => console.log(error) );
I wasn't satisfied with any of the suggested solutions, so I played a bit with Fetch API to find a way to handle both success responses and error responses.
Plan was to get {status: XXX, message: 'a message'} format as a result in both cases.
Note: Success response can contain an empty body. In that case we fallback and use Response.status and Response.statusText to populate resulting response object.
fetch(url)
.then(handleResponse)
.then((responseJson) => {
// Do something with the response
})
.catch((error) => {
console.log(error)
});
export const handleResponse = (res) => {
if (!res.ok) {
return res
.text()
.then(result => JSON.parse(result))
.then(result => Promise.reject({ status: result.status, message: result.message }));
}
return res
.json()
.then(result => Promise.resolve(result))
.catch(() => Promise.resolve({ status: res.status, message: res.statusText }));
};
I just checked the status of the response object:
$promise.then( function successCallback(response) {
console.log(response);
if (response.status === 200) { ... }
});
Hope this helps for me throw Error is not working
function handleErrors(response) {
if (!response.ok) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject({
status: response.status,
statusText: response.statusText,
});
}, 0);
});
}
return response.json();
}
function clickHandler(event) {
const textInput = input.value;
let output;
fetch(`${URL}${encodeURI(textInput)}`)
.then(handleErrors)
.then((json) => {
output = json.contents.translated;
console.log(output);
outputDiv.innerHTML = "<p>" + output + "</p>";
})
.catch((error) => alert(error.statusText));
}
Another (shorter) version that resonates with most answers:
fetch(url)
.then(response => response.ok ? response.json() : Promise.reject(response))
.then(json => doStuff(json)) //all good
//next line is optional
.catch(response => handleError(response)) //handle error

Categories