Imagine we have a function like so:
async function doSomethingWithFriends() {
let user, friends, friendsOfFriends = null;
try {
user = await getUser();
} catch(err){
return [401, err]
}
try {
friends = await getFriends(user);
} catch (err){
return [500, err];
}
try {
friendsOfFriends = await getFriendsOfFriends(friends);
} catch(err){
return [500, err]
}
return doFriendsOfFriends(friendsOfFriends);
}
instead is there some established pattern to avoid this somewhat boilerplate code?
There are two problems with the above code:
- it's noisy
- we cannot use
const
One solution is to only use try-catch in the caller functions, but I am wondering if there is a way to solve it all the way down.
CodePudding user response:
Are you using Expressjs
or something ? Please provide more information. I will assume you are making an API.
You can create a middleware that would handle all the error in your controller. Then in your controller you only need to throw or pass the error into next middleware. Example below.
error handle middleware
export function errorHandlingController(error: ErrorRequestHandler, _req: Request, res: Response, _next: NextFunction): void {
let errorCode: number
if (error instanceof RequestPayloadError) {
errorCode = 400
} else if (error instanceof UnauthorizedError) {
errorCode = 401
} else if (error instanceof NotFoundError) {
errorCode = 404
} else {
errorCode = 500
}
res.status(errorCode).json(<GeneralResponse>{
status: responseStatus.error,
message: error.toString()
})
}
user controller
export function getMyProfile(_req: Request, res: Response, next: NextFunction): void {
try {
const user = res.locals.user
if (!user) throw new UnauthorizedError('Author id not identified')
res.status(200).json({
status: responseStatus.success,
user: user
})
} catch (error: unknown) {
next(error)
}
}
CodePudding user response:
In this case each function you can define custom exception. In doSomethingWithFriends
only one try catch
in used.
Sample code below:
(async function doSomethingWithFriends() {
async function getUser() {
throw 'getUser'
}
async function getFriends() {
throw 'getFriends'
}
async function getFriendsOfFriends() {
throw 'getFriendsOfFriends'
}
let user, friends, friendsOfFriends = null;
try {
user = await getUser();
friends = await getFriends(user);
friendsOfFriends = await getFriendsOfFriends(friends);
} catch(err){
console.log(err)
if (err) {
// custom return what you want
}
}
return doFriendsOfFriends(friendsOfFriends);
}())
CodePudding user response:
The catch phrase of Promise API can be combined with switch/if statements. Something like below (did not test it for syntax err etc.):
async function doSomethingWithFriends() {
let errID = 0;
return getUser()
.then(user => ( errID,getFriends(user)))
.then(friends => ( errID, getFriendsOfFriends(friends)))
.then(fof => ( errID, doFriendsOfFriends(fof)))
.catch(err => {switch (errID) {
case 0:
return [401, err];
case 1:
return [500, err];
...
}});
}