2015-07-25 14 views
10

Chciałbym utworzyć własną klasę błędów w TypeScript, rozszerzając rdzeń Error, aby zapewnić lepszą obsługę błędów i niestandardowe raportowanie. Na przykład chcę utworzyć klasę HttpRequestError z adresem URL, odpowiedzią i treścią przekazaną do jej konstruktora, która odpowiada za żądanie HTTP do http://example.com nie powiodło się z kodem stanu 500 i wiadomością: coś poszło nie tak i prawidłowe śledzenie stosu.Niestandardowa klasa błędów w TypeScript

Jak rozszerzyć klasę błędów rdzenia w TypeScript? Już znalazłem post w SO: How do I extend a host object (e.g. Error) in TypeScript, ale to rozwiązanie nie działa dla mnie. Używam TypeScript 1.5.3

Jakieś pomysły?

+1

, w jaki sposób zrobić te odpowiedzi nie pomóc? Nie możesz jeszcze rozszerzyć klasy Error. [To nadchodzi w 1.6.] (Https://github.com/Microsoft/TypeScript/pull/3516) –

+0

@DavidSherret Mam kilka błędów kompilacji, które, jak widzę, nie zostały zgłoszone przez 'tsc' we wcześniejszych wersjach . –

Odpowiedz

7

Do chwili wykonania około 1,6 rolki, robię własne rozszerzalne klasy.

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

Tak, moje rozwiązania są znane, jedyne, co zastanawiałem się, to jak rozszerzyć klasy podstawowe w taki sam sposób, jak te w projekcie. Smutno, nie widzę żadnej daty, kiedy TS 1.6 mógł zostać wydany. Więc, myślę, że twoje rozwiązanie jest jak najbliższe moim oczekiwaniom, dzięki! :) –

11

Używam maszynopis 1,8 i to w jaki sposób mogę używać niestandardowych klas błędach:

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); 

Dla maszynopis wersjach starszych niż 1.8, trzeba zadeklarować Error:

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

Powinieneś być ostrożny z tym podejściem. Wydaje mi się, że przeczytałem, że wywoływanie własności stosu jest DUŻE i powinno się go unikać w kodzie. Myślę, że możesz dodać znaczną ilość narzutów dla niestandardowych błędów. Z dokumentacji "Ciąg reprezentujący ślad stosu jest generowany leniwie, gdy uzyskuje się dostęp do właściwości error.stack." – StewartArmbrecht

+0

Nie rozumiem, dlaczego jest to konieczne w pierwszej kolejności: 'this.stack = ( new Error()). Stack;" Powinien być dziedziczony z klasy Error, yes? – DarkNeuron

36

maszynopis 2.1 miał przełomowy zmiany dotyczące Rozszerzanie Zabudowy jak błąd.

Z 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; 
    } 
} 

Następnie można użyć:

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

Warto wspomnieć, że 'Object.setPrototypeOf' musi być wywołany natychmiast po wywołaniu' super (...) '. –

+6

Dziękuję za to, kosztowało mnie kilka naszych badań. Jak to nie generuje ostrzeżenia kompilatora, jest poza mną. –

+4

Dlaczego musimy dodać 'Object.setPrototypeOf (this, FooError.prototype);'? – Searene

Powiązane problemy