expressjs not throwing error on Parse queries (parse-server) - express

I have a parse-server setup on expressjs like here.
But sometimes it's not showing errors inside Parse functions. Example:
// Parse Server is setup
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
var pageQuery = new Parse.Query('Page');
pageQuery.get('id').then(function(page) {
someObject.undefinedProp = false;
res.send(page);
}, function(error) {
res.send(error);
});
});
No errors displayed, but with this code:
// Parse Server is setup
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
someObject.undefinedProp = false;
res.send('ok');
});
I have this error displayed:
ReferenceError: someObject is not defined
(For this example I have the exact same configuration as the Parse Server Example)
I just want to have the errors displayed inside my Parse functions.
Any ideas?
Thank you for your help!

Your issue is actually an issue caused by Promises.
When you call pageQuery.get('id'), the get method returns a Promise instance. The then method of the Promise is how you set up your callback that will fire on the successful completion of the get operation.
In order to get a reference to the error that should occur when you attempt to reference someObject.undefinedProp, you'll also need to set up an error handler on that Promise object by calling its catch method.
app.get('/', function(req, res) {
var pageQuery = new Parse.Query('Page');
pageQuery.get('id').then(function(page) {
someObject.undefinedProp = false;
// the error thrown here will be caught by the Promise object
// and will only be available to the catch callback below
res.send(page);
}, function(error) {
// this second callback passed to the then method will only
// catch errors thrown by the pageQuery.get method, not errors
// generated by the preceding callback
res.send(error);
}).catch(function (err) {
// the err in this scope will be your ReferenceError
doSomething(err);
});
});
Here, check out the following article and scroll down to the section heading "Advanced mistake #2: catch() isn't exactly like then(null, ...)".
https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html

Related

Express Mongoose throw custom error on callbacks

I'm trying to throw some custom error classes from mongoose callbacks.
Here is a simple code
const Restaurant = require('../models/Restaurant')
const { InternalServerError, UnauthorizedError } = require('../errors/errors')
const checkRestaurantAuthorization = async (token) => {
const restaurant = Restaurant.findOne({ 'token': token }, function (error, result) {
if (error) throw new InternalServerError()
else if (!result) throw new UnauthorizedError()
else return token
})
}
In my code checkRestaurantAuthorization is called by a simple middleware like
const restaurantMidlleware = async (req, res, next) => {
console.log('Request Type:', req.method);
try {
token = await checkRestaurantAuthorization('invalid_token')
next()
} catch (error) {
next(error)
}
}
Now if a restaurant instance with the given token is not found, the app crashes with throw er; // Unhandled 'error' event. From my testing it seems that executions stops when throw new UnauthorizedError() is called and I'm unable to identify the issue.
Here is also an example of a custom defined error if it's useful
class UnauthorizedError extends Error {
constructor(message) {
super(message)
this.name = 'Unauthorized request'
this.code = 403
Error.captureStackTrace(this, UnauthorizedError)
}
}
What am I missing?
have you tried putting your first block in 'try-catch' block?
The throw statement throws a user-defined exception. Execution of the current function will stop (the statements after throw won't be executed), and control will be passed to the first catch block in the call stack. If no catch block exists among caller functions, the program will terminate.
you can change code to promise or async-await
another source of the problem could be the fact that your are using async and callback in one function try to omit async then use it again
And there is no point in writing 'const restaurant =' in
const restaurant = Restaurant.findOne
since every found restaurant will be saved in callback's result variable
try this
function checkRestaurantAuthorization(token){
return new Promise(async(resolve, reject)=>{
try {
const restaurant = await Restaurant.findOne({ 'token': token });
if (!restaurant)
return reject(new UnauthorizedError())
else
return resolve(token)
}catch(error){
return reject(new InternalServerError())
}
})}
Even better approach would be using only async function with try-catch instead of returning a promise or any callback

express fetch promise will not resolve before render

I have an express route and I want to send back the result of a fetch to my pug template. I know my fetch URL works as I have checked it with postman and the data comes back as it should. I would like to store the fetch of the result to the variable called weather at the bottom of the route. My template looks for this variable to exist before adding weather to the template
I have also logged my form data to make sure the form is sending the data to my express server
I get this error in my command console when logging the return:
Promise { <pending> }
(node:18060) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'json' of undefined
I think the issue must be with my promise structure or perhaps it has to do with CORS not being enabled in my app? I'm not getting any errors and I'm hoping someone might have an answer for me??
router.post("/", async(req, res, next)=>{
console.log(req.body.selectedCity)
console.log(req.body.selectedState)
console.log(req.body.selectedZip)
var result = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${req.body.selectedCity}&units=imperial&appid=${apiKey}`)
.then(function(result) {
console.log(result.json())
})
.then((result)=>{
console.log(result.json())
res.render('index', {states:[
{
id:"none",
name:"choose"
},
{
id:"OH",
name:"Ohio"
},
{
id:"UT",
name:"Utah"
},
{
id:"VT",
name:"Vermont"
},
{
id:"VA",
name:"Virginia"
},
{
id:"WA",
name:"Washington"
},
{
id:"WV",
name:"West Virginia"
},
{
id:"WI",
name:"Wisconsin"
},
{
id:"WY",
name:"Wyoming"
}
],weather:result})
})
});
You have an uncorrect syntax on async/await.
You do not use .then in async/await but you just await the promise and store the result in a variable.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
var result = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${req.body.selectedCity}&units=imperial&appid=${apiKey}`)
.then(function(result) {
console.log(result.json())
})
.then((result)=>{
console.log(result.json())
res.render [...]
Becomes:
const result = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${req.body.selectedCity}&units=imperial&appid=${apiKey}`);
console.log(result.json())
res.render [...]
Try and avoid var as it may lead to unexpected behavior.
Try using axios as a fetch library, it's much cleaner than fetch.
https://www.npmjs.com/package/axios
This way it's just const result = await axios.get([...]
This should be structured this way instead -
fetch('url')
.then(result=>result.json)
.then(result=>res.render())
You should also remove async keyword from the callback function provide to router.post.

Nuxt.js - 'error not defined' when trying to throw 404 in failed await call within asyncData method

Starting to play with Nuxt.js this evening and mock blog data but having an issue with non existing data.
Heres my asyncData method when viewing a single blog post:
async asyncData({ params }) {
try {
const post = await axios.get(
`https://jsonplaceholder.typicode.com/posts/${params.id}`
)
return {
post: post.data
}
} catch (err) {
error({ statusCode: 404, message: 'Post not found' })
}
}
When visiting a valid ID and a 200 error is returned everything works as expected, but when the endpoint returns a 404 it tells me that 'error is undefined'
I could only find information on doing this error handling using a promise catch method as seen here: https://nuxtjs.org/guide/async-data/#handling-errors
How can I use the error method within the try catch error?
Thanks.
You have to inject the error object in your asyncData method to use it inside:
async asyncData({ error, params }) {
// your code
}

Angular GlobalErrorHandler and HttpErrorResponse - Resolver throwing badly formatted HttpErrorResponse

I've created global error handler in my Angular 6 application:
main error handler method:
handleError(error: Error | HttpErrorResponse) {
const router = this.injector.get(Router);
const notificationService = this.injector.get(NotificationsService);
this._logger(error);
if (!navigator.onLine) {
notificationService.displayNotification('error', 'timespan', {heading: 'Internet connection lost!', body: ''});
} else if (error instanceof HttpErrorResponse) {
notificationService.displayNotification('error', 'click', this._httpErrorMessage(error));
} else {
// CLIENT error
router.navigate(['/error-page']);
}
}
Problem:
Many of HTTP service calls are being performed in resolvers:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ClientDetailsModel> {
if (route.params.cif) {
const reqBody = new GetClientDetailsRequestModel({cif: route.params.cif, idWewPrac: this.userContext.getUserSKP()});
return this.clientsService.getClientDetails(reqBody)
.pipe(
map((clientDetails: { customerDetails: ClientDetailsModel }) => {
if (clientDetails.customerDetails) {
return clientDetails.customerDetails;
}
return null;
})
);
}
If Http error occurs in such a call, error received by my global error handler is formed as HttpErrorResponse wrapped inside Error (message of Error is HttpErrorResponse):
Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":400,"statusText":"OK","url":"https://...
If Http errors occurs outside of resolvers global error handler works perfectly fine.
To reach my goal (throwing HttpErrorResponse from resolver) I need to specify the way to handle error in error callback inside subscription, but I cannot do it because resolver is the one who manages subscription.
Is there a way to specify how resolver should handle errors?
I would like to avoid manual parsing of these wrapped errors.
I was searching for a solution, but could only create a work-a-round.
This will check for the HttpErrorResponse text and tries to parse the JSON which results into the real error object.
Not great at all, but better then nothing.
handleError(error: any): void {
console.error('Errorhandler catched error: ' + error.message, error);
// We need to have this little hack in oder to access the real error object
// The Angular resolver / promise wraps the error into the message, serialized as json.
// So we extract this error again.
// But first lets check if we actually dealing with an HttpErrorResponse ...
if (error.message.search('HttpErrorResponse: ')) {
// The error includes an HTTPErrorResponse, so we try to parse it's values ...
const regex = new RegExp('^.*HttpErrorResponse:\\s(\\{.*\\})$');
const matches = regex.exec(error.message);
if (matches !== null) {
// matches the regex, convert...
const httpErrorResponse = JSON.parse(matches[1]); // This is now the real error object with all the fields
this.handleHttpErrorResponse(httpErrorResponse);
} else {
// It contains HttpErrorResponse, but no JSON part...
this.toastr.error('There was an unknown communication error',
'Communication error',
{timeOut: 10000});
}
} else {
this.toastr.error('Unknown error occured',
'Well that should not happen. Check the log for more information...',
{timeOut: 10000});
}
}

RTCPeerConnection.createAnswer callback returns undefined object in mozilla for WebRTC chat

Following is my code to answer the incoming call:
var pc = connection.pc;
pc.setRemoteDescription(sdp,function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer,function() {
// code for sending the answer
})
})
})
The above code works fine for chrome, but when i run the same in mozilla, the answer obtained from pc.createAnswer callback is undefined. As a result of which it gives me following error:
TypeError: Argument 1 of RTCPeerConnection.setLocalDescription is not
an object.
The problem is you're not checking errors, specifically: not passing in the required error callbacks.
setRemoteDescription and setRemoteDescription require either three arguments (legacy callback style) or one (promises), but you're passing in two. Same for createAnswer minus one.
The browser's JS bindings end up picking the wrong overload, returning you a promise which you're not checking either, effectively swallowing errors.
Either add the necessary error callbacks:
var pc = connection.pc;
pc.setRemoteDescription(sdp, function() {
pc.createAnswer(function(answer) {
pc.setLocalDescription(answer, function() {
// code for sending the answer
}, function(e) {
console.error(e);
});
}, function(e) {
console.error(e);
});
}, function(e) {
console.error(e);
});
Or use the modern promise API:
var pc = connection.pc;
pc.setRemoteDescription(sdp)
.then(() => pc.createAnswer())
.then(answer => pc.setLocalDescription(answer))
.then(() => {
// code for sending the answer
})
.catch(e => console.error(e));
The promise API is available natively in Firefox, or through adapter.js in Chrome. See fiddle.
And always check for errors. ;)