throw statement is ignored within Nextjs middleware helper - javascript

I am writing middleware code for setting up authentication and token validation in my nextjs app. I am using throw instead of returning value from the helper function.
But throw (last statement) is not working in the following code:
async function validate(request: NextRequest) {
const tokenid = "test";
if (tokenid) {
try {
// in case of error
throw new Error("test");
} catch (error) {
console.error("validate: ", error);
}
}
throw new Error("tokenId validation failed");
}
This function is called within another function and where the last statement is simply ignored.
export async function googleAuthValidate(request: NextRequest) {
let response = NextResponse.next();
try {
validate(request);
console.log("throw didnt go into catch");
} catch (error) {
console.error(error);
response = NextResponse.rewrite("/unauthorized");
} finally {
return response;
}
}
I have created a repository for this issue for easy reproduction: repo

Related

How to throw custom error in async callout

I'm making a couple async API callouts and may throw a custom error depending on the outcome.
I'm deleting Objects from S3.
try {
await s3.deleteObject(bucketParams);
//S3 API doesn't provide resp on if obj successfully deleted. Therefore, check that it doesn't exist afterwards to verify instead
const err = await s3.headObject(bucketParams);
if (err & err.code === 'NotFound') return { code:200, message:`${key} successfully deleted` }
throw `Error deleting ${key}`;
} catch (error) {
throw new Error(500, error);
}
So the main catch can handle any exceptions thrown by those couple API callouts (error with network, bad key, bad authorization, etc..)
However, if the object didn't actually get deleted (so if it still exists)..I throw a custom error to get reported back to end user.
My question is if there's a better pattern to just throwing a custom error in your try and then having it get slurped up by your catch.
Thanks!
You can do a lot to be honest, you just need to work out what you want to capture. Heres a basic example. If you were using TypeScript you would get more power and type safety
class S3ObjectNotFound extends Error {
// Add other attributes you might like
code
constructor(message) {
super(message)
this.name = 's3/object-id-not-found'
this.code = 404
}
}
const someFunction = async (bucketParmas, key) => {
try {
try {
await s3.deleteObject(bucketParams)
} catch (s3Error) {
throw new S3ObjectNotFound(`Object with id ${bucketParmas} was not found`)
}
const err = await s3.headObject(bucketParams)
if (err && err.code === 'NotFound') {
return { code: 200, message: `${key} successfully deleted` }
}
throw AnotherErrorYouCouldMake()
} catch (error) {
throw new Error(500, error)
}
}
someFunction({...YourParams}, 'YourKey')

Mongoose and multiple save error handling

I'm using mongoose + express to build a simple MERN app.
I need to create multiple documents and save them, but I need to catch all errors.
I'm using this code and it works, but I'd like to handle all errors at once, not repeat the same code multiple times.
If I use try...catch block and remove the callback error handler, I obtain UnhandledPromiseRejectionWarning.
model.save((err, doc) => {
if (err) return console.error(`ERR ${err.message}`);
});
I've tried this:
export const init = async () => {
try {
const newDoc = new MyModel({ test: 'test'});
const savedDoc = await newDoc.save();
console.log('All done :)');
} catch (err) {
console.log('Error');
res.status(400).send(err);
}
}
But I can't catch the error: in debug mode, the program never enter the catch block and I obtain, in case of error for example:
UnhandledPromiseRejectionWarning: MongoError: E11000 duplicate key error collection
Any suggestion?
model.save()
.then(success => {
if(!success) {
// Handle your error
}
// Success
return model2.save();
})
.then(success2 => {
})
// etc..
.catch(err => {
// Handle your error
});
try{
const savedModel = await model.save();
console.log("Model created successfully");
res.status(200).send("Model created successfully");
}catch (err){
console.log(err);
res.status(400).send(err);
}

Axios instance promise.all error handling

I have the following code in my own async function that uses another imported function from module which is a custom wrap of axios inside try/catch block:
async function getCharacter (realmSlug, characterName) {
try {
const [{id, name, gender, faction, race, character_class, active_spec, realm, guild, level, last_login_timestamp, average_item_level, equipped_item_level}, {pets, unlocked_battle_pet_slots},{mounts}] = await Promise.all([
getCharacterSummary(realmSlug, characterName), -- custom axios instance
getCharacterPetsCollection(realmSlug, characterName),
getCharacterMountsCollection(realmSlug, characterName)
])
....
return result;
} catch (error) {
console.log(error.code);
if (error.response.status === 404 || error.response.status === 403) {
console.error(`${getCharacter.name},${characterName}#${realmSlug}`);
}
return { name: characterName, realm: realmSlug }
}
}
The problem is that if I use promise.all according to Stackoverflow 1,2 I can not handle errors. So the problem is when I call function to execute, my errors doesn't handle in (catch) block. At all. Even if I don't need print them, anyway I receive messages in console about 404 errors, but console.log(error.code) still gives me nothing. For example:
So is there any way to handle this annoying error messages in console somehow?
For example using .catch somewhere? Or using for await ... of or rxJS instead if it's possible?
Exporting function and using .catch
Even if I export this function getCharacter in another .js file and use the following code:
const getCharacter = require('./getCharacter');
let bulkCharacters = [{realmSlug, characterName},{realmSlug, characterName},... ,n] //array of characters for getCharacter request
const promises = bulkCharacters.map(async ({realmSlug, characterName}) => {
try {
return await getCharacter(realmSlug, characterName);
} catch (e) {
console.log(e)
}
});
let test = await Promise.all(promises)
.catch(function(arrayOfPromises, err) {
// log that I have an error, return the entire array;
console.log('A promise failed to resolve', err);
return arrayOfPromises;
})
.then(function(arrayOfPromises) {
console.log(arrayOfPromises)
})
;
console.log('stop')
I still receive errors in console, without triggering catch block inside getCharacter function or this file in which this function was imported and catch block is outside the function.

Why Method call inside onSubmit throws error?

I try to call metetor method but it is throwing me error "Uncaught TypeError: Meteor.call is not a function" but when I try to call same in another file inside imports/api/some.js this works, meaning the call code is correct but it is working inside onSubmit why ? Here is github url
File : imports/ui/otp.js
onSubmit(e) {
e.preventDefault();
let otp = this.refs.otp.value.trim();
Meteor.call('find-otp', otp, (error, result) => {
if(error) {
console.log('otp error check', error);
} else {
console.log('otp res check', result);
}
});
}
File : imports/api/db.js
Meteor.methods({
'find-otp' (otp) {
// if(!this.userId) {
// throw new Meteor.Error('not-authorized');
// }
console.log('otpcheck', otp);
return true;
// return otp; // also I try this
}
});
Make sure you properly import Meteor:
import { Meteor } from 'meteor/meteor'

Server side simple function called in Meteor methods error handling

In my meteor project, I want to use generic functions in my Meteor.methods
(Mostly because I don't want users to call this functions from the client).
I'm defining this function in another file :
const ldapPing = (callback) => {
try {
ldapAuth.client = createClient({
url: Meteor.settings.private.LDAP.URL,
});
ldapAuth.client.on('error', () => {
throw new Meteor.Error('500', 'Cant join.');
});
callback(null, true);
} catch (exception) {
callback(exception, null);
}
};
And I'm calling it in my meteor methods like this :
'test.ldap': function testLdap() {
try {
const future = new Future();
ldapPing((error, result) => {
console.log('ERROR : ' + error);
console.log('RESULT : ' + result);
if (error) {
future.throw(error);
} else {
future.return(true);
}
});
return future.wait();
} catch (exception) {
throw exception;
}
},
However, the Meteor.error is not returned to the Meteor method and is immediatly throw from the simple function ldapPing, which stops meteor with "Exited with code: 1".
Any idea why ?
(This example is made for this question, ofc in this case there is no benefits to externalize this function)

Categories