Maison > interface Web > js tutoriel > Gestion élégante des erreurs et sécurité de type de bout en bout avec Hono RPC

Gestion élégante des erreurs et sécurité de type de bout en bout avec Hono RPC

Barbara Streisand
Libérer: 2024-12-25 11:18:11
original
818 Les gens l'ont consulté

Elegant Error Handling and End to End typesafety with Hono RPC

J'ai toujours eu une relation amour-haine avec la gestion des erreurs de JavaScript. Sa dépendance à l'égard des blocs try-catch et le lancement d'exceptions peuvent fonctionner pour d'autres, mais cela me frustre parfois.

Considérez ce modèle typique de gestion des erreurs JavaScript :

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);
  }
}
Copier après la connexion

Cela fait beaucoup de code et nous ne connaissons toujours pas le type d'erreur.

Mon opinion est que lorsque vous traitez des erreurs, vous voulez savoir ce qui a causé l'erreur, d'où elle vient et de quel type d'erreur il s'agit et la gérer immédiatement. Surtout lorsque vous êtes dans un environnement serveur. Pour moi


La voie Golang

Je préfère gérer les erreurs comme la façon dont Golang les gère, essentiellement les erreurs sous forme de valeurs.

data, err := getData()
if err != nil {
  // handle error
}
Copier après la connexion

De cette façon, vous gérez l'erreur immédiatement et vous n'avez pas à vous soucier du reste du code en cours d'exécution en cas d'erreur.

Supabase fait la même chose avec sa bibliothèque supabase-js.

const { data, error } = await supabase.from("users").select("*");
if (error) {
  // handle error
}
Copier après la connexion

Gestion gracieuse des erreurs avec Hono RPC

Parlons de la star principale de la série

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: "/" });
};
Copier après la connexion
Copier après la connexion

Cette fonction n'a peut-être pas l'air de grand-chose, mais elle fournit des paramètres JSON de type sécurisé via RPC. Il gère toutes les erreurs et renvoie un objet contenant soit des données, soit une erreur, avec le type de données déduit de la définition RPC en fonction du type de retour du point de terminaison.


Configuration de la gestion gracieuse des erreurs

Configurez Hono Rpc à l'aide de la documentation officielle

Configuration du gestionnaire d'erreurs Hono

Le backend doit toujours renvoyer une réponse texte avec le message d'erreur et le code d'état.

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);
Copier après la connexion

Sur la base de la documentation de Hono, vous devriez lancer HTTPException comme ceci

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" });
});
Copier après la connexion

Maintenant, nous savons que s'il y a une erreur, nous recevrons toujours une réponse textuelle avec le message d'erreur et le code d'état.


3. Configuration du gestionnaire d'erreurs dans le 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;
Copier après la connexion

callRpc déduira automatiquement le type de données en fonction de la définition RPC et renverra un objet contenant soit des données, soit une erreur.


4. Utilisation

Tout est sécurisé, de ce que vous envoyez à ce que vous recevez

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: "/" });
};
Copier après la connexion
Copier après la connexion

J'ai travaillé dans une base de code où elle est configurée comme ceci et c'est l'expérience de développeur la plus fluide que j'ai eue. Je suis juste là pour le partager.


Inconvénients

  • Le backend se limite à renvoyer du texte pour les erreurs et du JSON pour les réponses réussies
  • Faire ce modèle s'éloigne de la manière idiomatique de gérer les erreurs en javascript
  • Vous devez gérer l'erreur tout de suite, ce qui n'est peut-être pas ce que vous souhaitez

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal