2015-07-25 7 views
10

Vorrei creare la mia classe di errore in TypeScript, estendendo il core Error per fornire una migliore gestione degli errori e rapporti personalizzati. Ad esempio, desidero creare una classe HttpRequestError con url, response e body passati nel suo costruttore, che risponde con richiesta Http a http://example.com non riuscita con codice di stato 500 e messaggio: Qualcosa è andato storto e traccia dello stack corretta.Classe di errore personalizzata in TypeScript

Come estendere la classe di errore di base in TypeScript? Ho già trovato post in SO: How do I extend a host object (e.g. Error) in TypeScript ma questa soluzione non funziona per me. Uso TypeScript 1.5.3

Qualche idea?

+1

In che modo queste risposte non aiuterà? Non è ancora possibile estendere la classe Error. [Che sta arrivando in 1.6.] (Https://github.com/Microsoft/TypeScript/pull/3516) –

+0

@DavidSherret Ho alcuni errori di compilazione che, come vedo, non sono stati segnalati da 'tsc' nelle versioni precedenti . –

risposta

7

Fino a quando rotola intorno a 1,6, ho appena creato le mie classi estendibili.

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

Sì, le mie soluzioni sono familiari, l'unica cosa che mi sono chiesto è come estendere le classi principali allo stesso modo di quelle del progetto. Sinceramente, non vedo alcuna data in cui TS 1.6 potrebbe essere rilasciato. Quindi, beh, penso che la tua soluzione sia la più vicina alle mie aspettative finora, grazie! :) –

11

Sto usando dattiloscritto 1.8 e questo è come uso le classi di errore personalizzate:

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

Per le versioni dattiloscritto di età superiore a 1.8, è necessario dichiarare Error:

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

Si dovrebbe fare attenzione con questo approccio. Ho pensato di leggere che chiamare la proprietà dello stack è ESPENSIVO e dovrebbe essere evitato nel codice. Penso che potresti aggiungere una quantità significativa di spese generali per gli errori personalizzati. Dalla documentazione "La stringa che rappresenta la traccia dello stack viene generata pigramente quando si accede alla proprietà error.stack." – StewartArmbrecht

+0

Non capisco perché sia ​​necessario in primo luogo: 'this.stack = ( new Error()). Stack;' Dovrebbe essere ereditato dalla classe Error, sì? – DarkNeuron

36

dattiloscritto 2.1 ha avuto una rottura cambiamenti per quanto riguarda Estendere built-in come errore.

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

Quindi è possibile utilizzare:

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

Vale la pena ricordare che 'Object.setPrototypeOf' deve essere chiamato immediatamente dopo ogni chiamata' super (...) '. –

+6

Grazie per questo, mi è costato un po 'di ricerca. Il modo in cui questo non genera un compilatore-avviso è oltre me. –

+4

Perché dobbiamo aggiungere 'Object.setPrototypeOf (this, FooError.prototype);'? – Searene