2015-07-25 3 views
10

Я хотел бы создать свой собственный класс ошибок в TypeScript, расширяя ядро ​​Error, чтобы обеспечить лучшую обработку ошибок и настраиваемую отчетность. Например, я хочу создать класс HttpRequestError с URL-адресом, ответом и телом, переданным в его конструктор, который отвечает . Запрос Http на http://example.com не выполнен с кодом состояния 500 и сообщением: что-то пошло не так и правильная трассировка стека.Пользовательский класс ошибок в TypeScript

Как расширить класс ошибок ядра в TypeScript? Я уже нашел сообщение в SO: How do I extend a host object (e.g. Error) in TypeScript, но это решение не работает для меня. Я использую TypeScript 1.5.3

Любые идеи?

+1

Каким образом сделать эти ответы не поможет? Вы еще не можете расширить класс Error. [Это в 1.6.] (Https://github.com/Microsoft/TypeScript/pull/3516) –

+0

@DavidSherret У меня есть некоторые ошибки компиляции, которые, как я вижу, не были отправлены 'tsc' в более ранних версиях , –

ответ

7

До тех пор пока 1.6 не свертывается, я только что делал свои собственные расширяемые классы.

class BaseError { 
    constructor() { 
     Error.apply(this, arguments); 
    } 
} 

BaseError.prototype = new Error(); 

class HttpRequestError extends BaseError { 
    constructor (public status: number, public message: string) { 
     super();  
    } 
} 

var error = new HttpRequestError(500, 'Server Error'); 

console.log(
    error, 
    // True 
    error instanceof HttpRequestError, 
    // True 
    error instanceof Error 
); 
+0

Да, мои решения знакомы, единственное, о чем я подумал, - это то, как расширить основные классы так же, как и их проекты. К сожалению, я не вижу ни одной даты, когда может быть выпущен TS 1.6. Итак, хорошо, я думаю, что ваше решение ближе всего к моим ожиданиям, спасибо! :) –

11

Я использую машинопись 1.8 и это, как я использую пользовательские классы ошибок:

UnexpectedInput.ts

class UnexpectedInput extends Error { 

    public static UNSUPPORTED_TYPE: string = "Please provide a 'String', 'Uint8Array' or 'Array'."; 

    constructor(public message?: string) { 
    super(message); 
    this.name = "UnexpectedInput"; 
    this.stack = (<any> new Error()).stack; 
    } 

} 

export default UnexpectedInput; 

MyApp.ts

import UnexpectedInput from "./UnexpectedInput"; 

... 

throw new UnexpectedInput(UnexpectedInput.UNSUPPORTED_TYPE); 

Для машинописи версий старше 1.8, вам нужно объявить Error:

export declare class Error { 
    public message: string; 
    public name: string; 
    public stack: string; 
    constructor(message?: string); 
} 
+1

Вы должны быть осторожны с этим подходом. Я думал, что прочитал, что вызов свойства стека является ДОРОГОЙ, и его следует избегать в коде. Я думаю, вы могли бы добавить значительную часть накладных расходов для пользовательских ошибок. Из документации «Строка, представляющая трассировку стека, создается с лёгкостью при доступе к свойству error.stack». – StewartArmbrecht

+0

Я не понимаю, почему это необходимо в первую очередь: 'this.stack = ( new Error()). Stack;' Должно быть унаследовано от класса Error, да? – DarkNeuron

36

машинописи 2,1 была распадающиеся изменения относительно Расширения встроенных модулей, как ошибка.

TypeScript breaking changes documentation От

class FooError extends Error { 
    constructor(m: string) { 
     super(m); 

     // Set the prototype explicitly. 
     Object.setPrototypeOf(this, FooError.prototype); 
    } 

    sayHello() { 
     return "hello " + this.message; 
    } 
} 

Затем вы можете использовать:

let error = new FooError("msg"); 
if(error instanceof FooError){ 
    console.log(error.sayHello(); 
} 
+5

Стоит отметить, что 'Object.setPrototypeOf' нужно вызывать сразу после любых вызовов' super (...) '. –

+6

Спасибо за это, стоило мне нескольких наших исследований. Как это не порождает предупреждение о компиляторе, это выходит за рамки меня. –

+4

Зачем нам нужно добавлять 'Object.setPrototypeOf (this, FooError.prototype);'? – Searene

Смежные вопросы