How to build an Error object instead of give its a string? https://codesandbox.io/s/pwr973487x
async function getUrl() {
try {
const res = await axios.get('https://httpstat.us/500')
} catch(e) {
const errorObj = {
status: 500,
message: 'Internal server error, something is not defined etc'
}
throw new Error('err') //how to build object?
}
}
I want throw Error() to return errorObj. Do I have to do my own class to do that or I can modify the existing Error class for that? I need that so it standardize my error message of my different set of Apis.
You can use the error object returned from catch
try {
const res = await axios.get('https://httpstat.us/500')
} catch(e) {
e.message = 'Internal server error, something is not defined etc';
throw e;
}
You can just add a field to the Error object, e.g.
var err = new Error('Internal Server error');
err.customField = { someProperty: 'some value'};
console.log(err);
And then you can throw it as normal:
throw err;
When you catch the error (higher up in the call stack) you can pull out the custom field:
try
{
throw err;
}
catch (e)
{
console.error(e);
console.log(e.customField);
}
With ES6 onwards you can also create your own error class:
class MyError extends Error {
constructor(message, customValue) {
super(message);
this.field = customValue;
}
get customField() {
return this.field;
}
set customField(obj) {
this.field = obj;
}
};
var ex = new MyError('Error message', {someProperty: 'some value'});
console.dir(ex);
console.log('My custom error details: ', ex.customField);
you could try with the cause propoty of :
TS has inaccurate value type about it at present, this is being discussed on the official to revolve it.
try {
throw new Error('Failed in some way', {
cause: {status: 400}
});
} catch(e) {
console.log(e); // Error('Failed in some way')
console.log(e.cause) // {status: 400}
}
or throw the Error instance with the custom property
try {
const error = new Error('Failed in some way');
error.status = 400;
throw error;
} catch(e) {
console.log(e); // Error('Failed in some way')
console.log(e.status) // 400
}
Related
Environment
Node v19.0.0
Applied #babel/preset-typescript
Applied #babel/preset-env
tsconfig.json target set to ES6
Background
The below code has a try/catch block where if the new URL constructor fails, I catch the error and handle it using if (err instanceof TypeError)....
Issue
The problem I'm facing is that I have been unable to get err instanceof TypeError to ever be true.
I have tested in my browser that invalid urls passed to URL() throw TypeErrors.
Here are some other observations from console.logging my node environment:
err instanceof Error => false
err instanceof TypeError => false
console.log(err.name) => TypeError
console.log(err.message) => Invalid URL
console.log(err.constructor) => [Functn: TypeError]
function getURLsFromHTML(htmlBody: string, baseURL: string) {
const urls: string[] = []
const dom = new JSDOM(htmlBody)
const linkElements = dom.window.document.querySelectorAll("a")
for (const link of linkElements) {
if (link.href.slice(0, 1) === "/") {
// relative URL
try {
const url = new URL(`${baseURL}${link.href}`)
urls.push(url.href)
}
catch (err) {
if (err instanceof TypeError) {
console.log("Err with relative url", err.message)
}
else {
console.log("Else is logged")
}
}
}
else {
// absolute
try {
const url = new URL(`${link.href}`)
urls.push(url.href)
}
catch (err) {
if (err instanceof TypeError) {
console.log("Err with absolute url", err.message)
}
else {
console.log("Could not find type of err")
}
}
}
}
return urls
}
Why is err not typed as a TypeError, when the only possible failure in the try/catch block is TypeError?
async deleteUser(userId: string): Promise<boolean> {
try {
const userToDelete = await userModel.findByIdAndDelete(userId)
if(!userToDelete) {
throw new Error(`User with id: ${userId} does not exist`)
}
return true
} catch {
throw new Error("Something wrong with the database");
}
}
Wanted result:
If UserId is valid but non-existing in DB throw first error
If UserId is not valid or any other type of error throw second error
Current result:
If UserId is valid but non-existing in DB throw SECOND error
If UserId is not valid or any other type of error throw second error
Well you're throwing an exception inside a try block, which will be caught, and your catch block then re-throws a different exception. You can either inspect the caught exception
async deleteUser(userId: string): Promise<boolean> {
try {
const userToDelete = await userModel.findByIdAndDelete(userId)
if (!userToDelete) {
throw new Error(`User with id: ${userId} does not exist`)
}
return true
} catch(e) {
if (e.message == `User with id: ${userId} does not exist`) throw e
else throw new Error("Something wrong with the database")
}
}
(Checking an e.code you put on the error with Object.assign, or testing for an Error subclass with instanceof, would be nicer than testing the message)
or put the try closer around the await … statement whose errors you want to handle:
async deleteUser(userId: string): Promise<boolean> {
let userToDelete
try {
userToDelete = await userModel.findByIdAndDelete(userId)
} catch {
throw new Error("Something wrong with the database");
}
if (!userToDelete) {
throw new Error(`User with id: ${userId} does not exist`)
}
return true
}
which is nicer with .catch():
async deleteUser(userId: string): Promise<boolean> {
const userToDelete = await userModel.findByIdAndDelete(userId).catch(e => {
throw new Error("Something wrong with the database");
})
if (!userToDelete) {
throw new Error(`User with id: ${userId} does not exist`)
}
return true
}
This code was built to allow us to save errors to our database.
const logErrors = function (data) {
try {
let error = { date: new Date(), ...data };
databaseConnections[dbMappings['BACKEND_ERROR_DB_MAPPING']['default']].collection('BackendLogs').insert(error);
} catch (error) {
const slackLog = new Log();
slackLog.error(error.toString());
}
};
export default logErrors;
The code works OK and saves errors to our database, but it occasionally throws the error "0, logger 1.default) is not a function."
What could be the problem?
Example scenario
catch (error) {
// error.stack = error.stack + " " + JSON.stringify(this.data);
if (error) {
logErrors({ message: error }); <<<<<
}
}
In my mocha testframework, I have an it-block that might throw an error. How do I obtain this error in the afterEach-hook that is called afterwards? Is there any workaround if it is not directly passed?
...
afterEach(async function () {
var testObject = {
title: this.currentTest.title,
state: this.currentTest.state,
duration: this.currentTest.duration,
timedOut: this.currentTest.timedOut,
error: this.currentTest.err // I want the error object here
}
});
it('my title', () => {
try {
doSomethingThatMightThrowError();
} catch (err) {
throw new Error(err)
}
});
....
I am coding using co module on sail framework.
I want to catch InvalidError but error log says 'undefined'.
How can I fix this code?
Co module can't catch ErrorType specification??
detail: function (req, res) {
co(function *() {
let errors = [];
const text = req.param('text');
if (text.length <= 0) {
throw new InvalidError('text is required');
}
}).catch((InvalidError, err) => {
sails.log.warn(err);
errors.push(err.message);
req.flash('errors', errors);
res.redirect('/somewhere/view');
}).catch((Error, err) => {
sails.log.error(err);
res.serverError(err);
});
}
error log is here
warn: undefined
error: undefined
error: Sending empty 500 ("Server Error") response
The catch method only takes a single argument: err. Try:
.catch(err => {
sails.log.warn(err);
errors.push(err.message);
req.flash('errors', errors);
res.redirect('/somewhere/view');
})
You're not useing Bluebird, are you? The standard catch method does not have error type filtering, you'll need to do that yourself:
.catch(err => {
if (err instanceof InvalidError) {
sails.log.warn(err);
errors.push(err.message);
req.flash('errors', errors);
res.redirect('/somewhere/view');
} else if (err instanceof Error) {
sails.log.error(err);
res.serverError(err);
} else {
console.error("You've thrown a non-error! Shame on you!");
}
});