出于某种原因,在下面的代码段中,构造函数委托似乎不起作用:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
运行该命令得到的消息是:"。有什么想法,为什么,或者是否有更好的方法来创建一个新的错误子类?是否有一个问题,应用到本机错误构造函数,我不知道?
我喜欢这样做:
利用name,使toString()抛出"{code}: {message}"
将相同的东西返回给super,这样在stacktrace中就会显示相同的内容
将代码附加到错误。在代码中检查/解析代码比检查消息(例如,您可能希望本地化消息)更好
将消息附加到错误。message作为error.toString()的替代
class AppException extends Error {
constructor(code, message) {
const fullMsg = message ? `${code}: ${message}` : code;
super(fullMsg);
this.name = code;
this.code = code;
this.message = fullMsg;
}
toString() {
return this.message;
}
}
// Just a code
try {
throw new AppException('FORBIDDEN');
} catch(e) {
console.error(e);
console.error(e.toString());
console.log(e.code === 'FORBIDDEN');
}
// A code and a message
try {
throw new AppException('FORBIDDEN', 'You don\'t have access to this page');
} catch(e) {
console.error(e);
console.error(e.toString());
console.log(e.code === 'FORBIDDEN');
}
以下是Mozilla官方文档中的错误。
function NotImplementedError(message) {
var instance = new Error(message);
instance.name = 'NotImplementedError';
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
if (Error.captureStackTrace) {
Error.captureStackTrace(instance, NotImplementedError);
}
return instance;
}
NotImplementedError.prototype = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
});
这是我的实现:
class HttpError extends Error {
constructor(message, code = null, status = null, stack = null, name = null) {
super();
this.message = message;
this.status = 500;
this.name = name || this.constructor.name;
this.code = code || `E_${this.name.toUpperCase()}`;
this.stack = stack || null;
}
static fromObject(error) {
if (error instanceof HttpError) {
return error;
}
else {
const { message, code, status, stack } = error;
return new ServerError(message, code, status, stack, error.constructor.name);
}
}
expose() {
if (this instanceof ClientError) {
return { ...this };
}
else {
return {
name: this.name,
code: this.code,
status: this.status,
}
}
}
}
class ServerError extends HttpError {}
class ClientError extends HttpError { }
class IncorrectCredentials extends ClientError {
constructor(...args) {
super(...args);
this.status = 400;
}
}
class ResourceNotFound extends ClientError {
constructor(...args) {
super(...args);
this.status = 404;
}
}
示例用法#1:
app.use((req, res, next) => {
try {
invalidFunction();
}
catch (err) {
const error = HttpError.fromObject(err);
return res.status(error.status).send(error.expose());
}
});
示例用法#2:
router.post('/api/auth', async (req, res) => {
try {
const isLogged = await User.logIn(req.body.username, req.body.password);
if (!isLogged) {
throw new IncorrectCredentials('Incorrect username or password');
}
else {
return res.status(200).send({
token,
});
}
}
catch (err) {
const error = HttpError.fromObject(err);
return res.status(error.status).send(error.expose());
}
});