javascript - Berik en fanget feil og kast den på nytt i angular/typescript


Jeg er ny innen frontend-utvikling - jeg har vært kun backend de siste årene. Jeg prøver å fjerne en feildempende mekanisme i en hjelpefunksjon og kaste feilen som ble ignorert på nytt med mer informasjon. I den tilpassede ErrorHandleren vil jeg fange feilen og sende informasjonen til en backend-tjeneste. Jeg vet ikke hvordan jeg skal gjøre dette på riktig måte. Kastingen (forenklet):

class Helper {
  public doStuff(input: string): string {
    try {
      return mightThrowAnException(input);
    } catch (err) {
      (err as any).inputData = input; // this destroys the error data
      throw err;
    }
  }
}

Og ta dette med

export class GlobalErrorHandler extends ErrorHandler {

  constructor(
    private injector: Injector,
  ) {
    super();
  }

  public handleError(error: Error) {
    let loggingData: any = {
      errorMessage: error.message,
    }

    if (typeof (error as any).inputData !== "undefined") { // would like to replace this duck-typing, too
      loggingData = {
        ...loggingData,
        inputData: (error as any).inputData,
      }
    }

    // ... more stuff here

    console.log(loggingData); // will send the data to the logging server ITRL
  }
}

For å berike feilen prøvde jeg allerede å bruke @jsdevtools/ono-pakken:

class HelperWithOno {
  public doStuff(input: string): string {
    try {
      return mightThrowAnException(input);
    } catch (err) {
      throw ono(err, {inputData: input});
    }
  }
}

Som fikk jobben gjort. Dessverre liker ikke TS-linteren bruken av symbol (https://github.com/JS-DevTools/ono/issues/13), så jeg får en rød bygge-pipeline.

I PHP med Zend ville jeg laget en klasse som utvider den generelle Exception i namespace til hjelpen og lagt til inputData-egenskapen. Da ville jeg kunne sjekke typen av den fangede unntaket og håndtere det på ønsket måte.

Men jeg er ganske ny på Angular og TypeScript og er ikke sikker på hvordan jeg skal utføre denne oppgaven.

  • Jeg kunne utvide Error-klassen, men

    • må jeg kopiere hver egenskap fra den "forrige" feilen manuelt? Eller bør jeg introdusere en annen egenskap previousError for å lagre den opprinnelige feilen?
    • hvor (katalog) lagrer klassefilen?
    • Bør jeg lage en injiserbar fabrikk for feilene?
    • I hvilket modul ville en erfaren utvikler plassere denne klassen?
  • Vent til ono er fikset
  • Noen andre beste praksiser?

Svar #1

Det var inget svar, så jeg legger bare ut min løsning; håper noen vil fortelle meg om den er feil/har feil og foreslå en bedre løsning.

Jeg opprettet en mappe med navnet errors i katalogen til klassen Helper. I denne katalogen er det en fil med klassen

export class ProcessError extends Error {
    public inputData: string;
    public originalError: Error;

    public constructor(error: Error, inputData: string) {
        const errorAsAny = error as any;

        if ('fileName' in errorAsAny) {
            // Firefox specific
            if ('lineNumber' in errorAsAny) {
                // @ts-ignore
                super(error.message, errorAsAny.filename, errorAsAny.lineNumber);
            } else {
                // @ts-ignore
                super(error.message, errorAsAny.filename);
            }
        } else {
            super(error.message);
        }

        // Let's apply some magic you can find at https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
        Object.setPrototypeOf(this, ProcessError.prototype);

        this.originalError = error;
        this.inputData = inputData;
        this.stack = error.stack.split('\n').join('\n'); // materialize stack; not sure whether required
    }
}

Nå er jeg i stand til å kaste unntaket med

class HelperWithCustomError {
  public doStuff(input: string): string {
    try {
      return mightThrowAnException(input);
    } catch (err) {
      throw new ProcessError(err, input);
    }
  }
}

og sjekke for instansen i stedet for å bruke duck-typing med

if (error instnaceof ProcessError)