I am trying to wrap Ajax into a Bluebird promise wrapper, but am receiving:
Error: Unhandled rejection (stack trace here...)
wrapper1.js
let fetch = require('./wrapper2');
function requestWeb(type, url, data) {
return new Promise(function(resolve, reject) {
url = config.serverUrl + url.trim();
let options = {
type: type,
data: data ? JSON.stringify(data) : null,
dataType: 'json',
contentType: 'application/json',
crossDomain: true,
timeout: 15000,
xhrFields: { withCredentials: true }
};
fetch(url, options)
.then(data => {
resolve(data);
})
.catch(err => {
console.log('web api error: ' + err.message);
notify('Please check your interet connection');
reject(err);
});
});
}
wrapper2.js
import Promise from 'bluebird';
export default function(url, options) {
return new Promise(function(resolve, reject) {
$.ajax(url, options)
.done((result) => {
resolve(result);
})
.fail((xhr, err) => {
let proxy = new Error();
proxy.message = err || 'error is null';
proxy.name = 'ajax error';
reject(proxy);
});
});
}
Please note Bluebird requires different error object on reject().
I figured it out, BlueBird wants to warn you that a reject() call has been fired but you are not catching it. So I was using...
requestWeb(type, url, data).then((result)=>{});
So to fix, do one of two things: add the .catch() to the end of the call, or remove the reject(err) from the promise.
Related
I can not get the .catch to work. I have tried multiple solutions like throw and the uncommented reject().
I am puzzled why it is not working, since I tested https://stackoverflow.com/a/47803880/7262739 which seems to work exactly the same, but resulting in a working .catch.
I get this error: Unhandled rejected promise: 404 Not Found as if I didn't handle the rejection.
simplified version of the code:
makeRequest(theUrlOne)
.then(result => makeRequest(theUrlTwo))
.catch(result => console.log(result)) // not working, but not the problem
.then(result => resolve('Success.'))
.catch(result => resolve('Failed.')) // the problem-child
function makeRequest(url, method, datatype, timeout) {
return new Promise(function (resolve, reject) {
http.simpleRequest({
'method': method || 'GET',
'url': url,
'dataType': datatype || 'json',
'timeout': timeout || 6000,
}, function (error, response) {
if (error) {
return Promise.reject(error)
// reject(error)
}
if (response.statusCode != 200) {
return Promise.reject(response.status)
// reject(response.status)
}
let parsed = JSON.parse(response.data)
resolve(parsed);
});
})
}
Turns out my first solution actually was working, but I misunderstood the output.
if (error) {
reject(error)
}
if (response.statusCode != 200) {
reject(response.status)
}
I have a method in a class that is supposed to only throw error log messages and then another method in another function that will get this errors and console them (for now).
The problem is that it just throws the error in the console and not in an upper level...
This are the methods from file1.ts:
private sendToApp2(App2Url: string, logObject: object) {
try
{
let uriOptions = {
host: this.hostname,
port: this.port,
path: '/App2',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Api-version': '1'
}
};
this.App2Call(uriOptions, JSON.stringify(logObject));
}
catch (err) {
throw err;
}
}
private App2Call(params: Object, data: string) {
return new Promise((resolve, reject) => {
try {
let req = http.request(params, (response) => {
response.on('data', (data) => {
resolve(data);
});
}).on('error', (err: Error) => {
reject(new Error(err.message));
});
req.write(data);
req.end();
}
catch (err) {
reject(new Error(err.message));
}
});
}
And in the second file, I do this logic to catch the error and console it:
GetErrors() {
try {
// initialize the class object
let getErrors = new FirstClass();
await getErrors.sendToApp2(this.App2Url, this.logObject);
}
catch (err) {
console.log(err);
}
}
It looks like a simple case of having forgotten to use async on the definition of sendToApp2. Since it's not async, there are no errors thrown during sendToApp2 since it returns before the promise from App2Call rejects.
Where you're using sendToApp2 you're using await, which suggests you're expecting it to return a promise, so just add async to the definition:
private async sendToApp2(App2Url: string, logObject: object) {
// ^^^^^
Then the try/catch can handle rejections as errors.
Side note: Right now, there's no point to the try/catch in sendToApp2, since all it does is throw err.
return a promise from the sendToApp2 and deal with the errors when you call the function
private sendToApp2(App2Url: string, logObject: object) {
let uriOptions = {
host: this.hostname,
port: this.port,
path: '/App2',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Api-version': '1'
}
};
return this.App2Call(uriOptions, JSON.stringify(logObject));
}
etErrors.sendToApp2(this.App2Url, this.logObject).then(
function(){},
function(err){ //error callback,or you can use catch();
alert(err);
});
I implement user-defined exception in javascript code but it is not catching the exception.
I am providing my code :
function sendRequest(URL, Data, authorization, requestType,cuboidName) {
var Response = new $.Deferred();
var json;
if (requestType.toString() == "GET") {
$.ajax({
url: URL,
type: "GET",
dataType: "json",
headers: {
'Authorization': authorization,
'Accept': 'application/json'
},
success: function (result) {
Response.resolve(result);
//console.log("Response : " + JSON.stringify(result) + "\n\n\n");
},
error: function(err){
throw new Error("Error Code:\t"+err.status+"\nReason:\tCuboid Download failed for Cuboid:"+cuboidName);
}
});
}
return Response.promise();
}
I am calling the sendRequest function from the following code :
async loadDatatypeCuboid(dataCuboid)
{
try
{
dataTypeCuboiId = "444";
var res3 = new $.Deferred();
Utils.sendRequest(this.baseUrl+"rest/v1/grid/"+dataTypeCuboiId+"?importTid=-1&view=LATEST&mode=0&baselineId=-1", null, Globals.authorization, "GET","Datatype").then(function (result) {
res3.resolve(result);
if (result.status == 500) {
return;
}
else{
}
});
return res3.promise();
}
catch (error)
{
console.log(error);
}
}
I am not able to catch the thrown error. The console is showing as :
Utils.js:26 Uncaught Error: Error Code: 500 Reason: Cuboid Download
failed for Cuboid:Datatype
can anyone suggest How to Handle Exceptions in JavaScript Promise?
Thanks in Advance
Hi I have following function returning promise
module.exports.getJwtToken = async() => {
const httpSearchAddressUXConfig = {
headers: {
Accept: 'application/json',
mock: false,
'Content-Type': 'application/json',
},
data: reqBody,
method: 'POST',
url: `${config.app.entTokens.host}`, // need to get from env variables
timeout: config.app.enterpriseHTTPTimeout
};
try {
const token = await axios(httpSearchAddressUXConfig);
return token.data;
} catch (err) {
throw err;
}
I have following test case which fails with unhandled Promise rejection error
it('should find Jwt token ', async(done) => {
const actualTokenfound = jwtTokenService.getJwtToken();
return actualTokenfound
.then(result => expect(result).toBe(Object))
.then(done);
});
Any Suggestions ?
If you define a async function, you don't need to use "done". I guess something like this it'll works.
it('should find Jwt token ', async () => {
const actualTokenfound = await jwtTokenService.getJwtToken();
expect(result).toBe(Object));
});
it('User is already present as a supplier', (done) => {
const store = mockStore({}, [{ type: 'get_user', data: { } }]);
return store.dispatch(userGetAction({ role: 'supplier' }, () => {})).then(() => {
try {
expect(store.getActions()[0].data.disabled).toEqual(true);
expect(store.getActions()[0].data.errormessage).toEqual('User is already present as a assitantbuyer');
} catch (err) {
console.log(err);
}
done();
}).catch(() => {
done();
});
});
Why it is passing and showing green status even it is Expected is not equal to Actual.
PASS src/actions/user-get-action-assistant-buyer.test.jsx
● Console
console.error node_modules/fbjs/lib/warning.js:33
console.log src/actions/user-get-action-assistant-buyer.test.jsx:25
{ Error: expect(received).toEqual(expected)
Expected value to equal:
"User is already present"
Received:
"User is already present"
at store.dispatch.then (/Users/prakashchandrabarnwal/Desktop/myProductInduct_CE_Admin/src/actions/user-get-action-assistant-buyer.test.jsx:23:57)
matcherResult:
{ actual: 'User is already present as a assitant buyer',
expected: 'User is already present as a assitantbuyer',
message: [Function],
name: 'toEqual',
pass: false } }
If i do not wrap expect inside try catch its silently going inside .catch()
thunk code returning UnhandledPromiseRejectionWarning:
const buyerAction = (data = {}, cb) => dispatch => axios({
method: 'POST',
url: `http://localhost:3001/api/manageUsers`,
headers: {
'x-access-token': authService.getAccessToken()
},
data
}).then(res => new Promise((resolve, reject) => {
if (res.status === 200 && res.data) {
dispatch({ type: 'buyer_created', data: res.data.message });
if (data.role === 'buyer') {
axios({
method: 'POST',
url: `http://localhost:3001/api/populateBuyerLookUp`,
headers: {
'x-access-token': authService.getAccessToken()
},
data
})
.then((response) => {
resolve(response);
}).catch((err) => {
reject(err);
});
}
cb(res.data.message);
} else {
reject(res);
}
}))
.catch(() => {
console.log('error');
});
(node:44182) 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(). (rejection id: 1)
So, your expect fails with an error, you catch this error and just log it, in other words, you mute the error. After all, you call "done" just like there is no error.
The code doing things just like you wrote: ignore and mute any errors. You have to remove all catch from your test
it('User is already present as a supplier', () => {
const store = mockStore({}, [{ type: 'get_user', data: { } }]);
return store
.dispatch(userGetAction({ role: 'supplier' }, () => {}))
.then(() => {
expect(store.getActions()[0].data.disabled).toEqual(true);
expect(store.getActions()[0].data.errormessage).toEqual('User is already present as a assitantbuyer');
});
});
You can return Promise from your test (There is no need to use done) and if promise fails, the whole test fails. that's all
UPD: regarding UnhandledPromiseRejectionWarning, I think it could be linked with your request to the "populateBuyerLookUp", this request completely out of the flow. I tried to fix it, but it difficult to understand what you want to do exactly
const buyerAction = (data = {}, cb) => dispatch => axios({
method: 'POST',
url: `http://localhost:3001/api/manageUsers`,
headers: {
'x-access-token': authService.getAccessToken()
},
data
})
.then((res) => {
dispatch({type: 'buyer_created', data: res.data.message});
let promise;
if (data.role === 'buyer') {
promise = axios({
method: 'POST',
url: `http://localhost:3001/api/populateBuyerLookUp`,
headers: {
'x-access-token': authService.getAccessToken()
},
data
});
}
return Promise.resolve(promise).then(() => res.data.message);
})
.then((message) => {
cb(message)
}).catch(()=>{console.log("error")});