Reputation: 1576
Suppose I have the following async function
export async function someAsyncFunction() {
const result = await fetchData();
return result[0].id;
}
In the route I have
router.post(
'/some-path',
handleErrorAsync(async (req: Request, resp: Response, _err: Errback) => {
const data = await someAsyncFunction();
resp.json(data)
})
);
And I have error handling functionalities that do
interface ResponseError extends Error {
statusCode: number;
}
// Middleware to respond with an error when error caught
export function handleError(
err: ResponseError,
_req: Request,
resp: Response,
_next: NextFunction
) {
if (err) {
resp.status(err.statusCode || 500).json(err);
}
}
export const handleErrorAsync = (func: Function) => (
req: Request,
res: Response,
next: NextFunction
) => {
func(req, res, next).catch((error: Error) => {
next(error);
});
};
So this works fine if for example fetchData
has an error response object, but this fails to print error objects when the error is a regular javascript error and instead it just prints {}
with 500 error.
For example in this line return result[0].id;
if the result is empty ([]
), then this would throw TypeError
, which will be caught by the handleError
middleware, but then the .json(err)
part will show only {}
Is there a way I can get both the servers errors (which are working correctly) and the internal server errors with that same middleware?
Upvotes: 0
Views: 160
Reputation: 1576
I fixed the issue using https://www.npmjs.com/package/serialize-error
import { serializeError } from 'serialize-error';
if (err) {
resp
.status(err.statusCode || 500)
.json(serializeError(err));
}
Upvotes: 0
Reputation: 2425
You could extend the toJSON
method of Error.
let a = new Error("hi")
console.log(JSON.stringify(a))
Error.prototype.toJSON = function () {
const alt = {};
// get all property
Object.getOwnPropertyNames(this).forEach((key) => {
alt[key] = this[key];
});
// only get message property
// alt["message"] = this["message"]
return alt;
}
console.log(JSON.stringify(a))
Then just call res.json(error)
, and you'll get the property of Error.
Because when you call res.json(parameter)
, express will trigger the toJSON
method of parameter.
You could read more in Is it not possible to stringify an Error using JSON.stringify?
.
But, I recommend only expose the "message" property in toJSON
method.
Upvotes: 1
Reputation: 332
I would suggest using res.send() in the error handler like
return res.status(500).send(err.message);
Upvotes: 0
Reputation: 1161
I can suggest destructuring the err body.
resp.status(err.statusCode || 500).json({message:err.message, error:err});
This will give you a message for every Native Error
Upvotes: 1