Heim >Web-Frontend >js-Tutorial >Elegante Fehlerbehandlung und End-to-End-Typsicherheit mit Hono RPC

Elegante Fehlerbehandlung und End-to-End-Typsicherheit mit Hono RPC

Barbara Streisand
Barbara StreisandOriginal
2024-12-25 11:18:11825Durchsuche

Elegant Error Handling and End to End typesafety with Hono RPC

Ich hatte schon immer eine Hassliebe zur Fehlerbehandlung von JavaScript. Die Abhängigkeit von Try-Catch-Blöcken und dem Auslösen von Ausnahmen mag für andere funktionieren, aber manchmal frustriert es mich definitiv.

Bedenken Sie dieses typische JavaScript-Fehlerbehandlungsmuster:

async function fetchData(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Error fetching data:", error.message);
  }
}

Das ist eine Menge Code und wir kennen die Art des Fehlers immer noch nicht.

Meiner Meinung nach möchte man beim Umgang mit Fehlern wissen, was den Fehler verursacht hat, woher er kommt und um welche Art von Fehler es sich handelt, und ihn sofort beheben. Vor allem, wenn Sie sich in einer Serverumgebung befinden. Für mich


Der Golang-Weg

Ich bevorzuge es, Fehler so zu behandeln, wie Golang sie behandelt, im Grunde Fehler als Werte.

data, err := getData()
if err != nil {
  // handle error
}

Auf diese Weise behandeln Sie den Fehler sofort und müssen sich keine Sorgen machen, dass der Rest des Codes ausgeführt wird, wenn ein Fehler auftritt.

Supabase macht dasselbe mit ihrer supabase-js-Bibliothek.

const { data, error } = await supabase.from("users").select("*");
if (error) {
  // handle error
}

Anmutige Fehlerbehandlung mit Hono RPC

Lassen Sie uns über den Hauptdarsteller der Show sprechen

const onSubmit = async (data: SignUpSchema) => {
  const res = await callRpc(api.auth.signup.$post({ json: data }));

  if (res.error) {
    toast.error(res.error);
    return;
  }

  toast.success("Account created successfully");
  router.navigate({ to: "/" });
};

Diese Funktion sieht vielleicht nicht viel aus, stellt aber typsichere JSON-Parameter über RPC bereit. Es behandelt alle Fehler und gibt ein Objekt zurück, das entweder Daten oder Fehler enthält, wobei der Datentyp aus der RPC-Definition basierend auf dem Rückgabetyp des Endpunkts abgeleitet wird.


Einrichten der eleganten Fehlerbehandlung

Richten Sie Hono Rpc mithilfe der offiziellen Dokumentation ein

Einrichten des Hono-Fehlerbehandlers

Das Backend sollte immer eine Textantwort mit der Fehlermeldung und dem Statuscode zurückgeben.

export const errorHandler = (err: Error | HTTPException, c: Context) => {
  console.log("=== Caught Error ===");
  if (err instanceof HTTPException) {
    return c.text(err.message, err.status);
  }
  if (err instanceof z.ZodError) {
    return c.text(err.errors.map((err) => err.message).join(",\n"), 400);
  }
  console.error(err);
  return c.text("Something went wrong", 500);
};

// Add as a errorHandler on the Hono instance
const app = new Hono();
app.onError(errorHandler);

Basierend auf der Hono-Dokumentation sollten Sie eine HTTPException wie folgt auslösen

import { HTTPException } from "hono/http-exception";

app.post("/", async (c, next) => {
  if (somethingWentWrong) {
    throw new HTTPException(401, { message: "Custom error message" });
  }
  return c.json({ message: "Success" });
});

Jetzt wissen wir, dass wir bei einem Fehler immer eine Textantwort mit der Fehlermeldung und dem Statuscode erhalten.


3. Einrichten des Fehlerhandlers im Frontend

import { ClientResponse, hc } from "hono/client";
import type { ApiRoutes } from "../../../backend/app";
const client = hc<ApiRoutes>("/");

export const callRpc = async <T>(
  rpc: Promise<ClientResponse<T>>
): Promise<{ data: T; error: null } | { data: null; error: string }> => {
  try {
    const data = await rpc;

    if (!data.ok) {
      const res = await data.text();
      return { data: null, error: res };
    }

    const res = await data.json();
    return { data: res as T, error: null };
  } catch (error) {
    return { data: null, error: (error as Error).message };
  }
};

export default client.api;

callRpc leitet automatisch den Datentyp basierend auf der RPC-Definition ab und gibt ein Objekt zurück, das entweder Daten oder einen Fehler enthält.


4. Nutzung

Alles ist typsicher, von dem, was Sie senden, bis zu dem, was Sie empfangen

const onSubmit = async (data: SignUpSchema) => {
  const res = await callRpc(api.auth.signup.$post({ json: data }));

  if (res.error) {
    toast.error(res.error);
    return;
  }

  toast.success("Account created successfully");
  router.navigate({ to: "/" });
};

Ich habe in einer Codebasis gearbeitet, die so eingerichtet ist, und es ist die reibungsloseste Entwicklererfahrung, die ich je hatte. Ich bin nur hier, um es zu teilen.


Nachteile

  • Das Backend ist auf die Rückgabe von Text für Fehler und JSON für Erfolgsantworten beschränkt
  • Mit diesem Muster weichen wir von der idiomatischen Art der Fehlerbehandlung in Javascript ab
  • Sie müssen den Fehler sofort beheben, was möglicherweise nicht Ihren Wünschen entspricht

Das obige ist der detaillierte Inhalt vonElegante Fehlerbehandlung und End-to-End-Typsicherheit mit Hono RPC. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn