Skip to content

Commit

Permalink
[Core] Gérer les erreurs d'API selon la norme RFC 7807
Browse files Browse the repository at this point in the history
  • Loading branch information
gideruette committed Nov 15, 2024
1 parent fe30418 commit dd62cf9
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
62 changes: 57 additions & 5 deletions packages/core/src/network/error-parsing.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,51 @@
import {messageStore} from "../stores/message";

/** Format attendu des erreurs JSON issues du serveur. */
export interface ErrorResponse {
[key: string]: any;
export interface ProblemDetail {
/**
* @description A URI reference [RFC3986] that identifies the problem type.
* This specification encourages that, when dereferenced, it provide human-readable documentation
* for the problem type (e.g., using HTML [W3C.REC-html5-20141028]).
* When this member is not present, its value is assumed to be "type" (string) - "about:blank".
*/
type?: string | "about:blank";

/**
* @description (number) - The HTTP status code ([RFC7231], Section 6)
* generated by the origin server for this occurrence of the problem.
*/
status: number;

/**
* @description A short, human-readable summary of the problem
* type. It SHOULD NOT change from occurrence to occurrence of the
* problem, except for purposes of localization (e.g., using
* proactive content negotiation; see [RFC7231], Section 3.4).
*/
title?: string;

/**
* @description A human-readable explanation specific to
* this occurrence of the problem.
*/
detail?: string;

/**
* @description A URI reference that identifies the specific occurrence of the problem.
* It may or may not yield further information if dereferenced.
*/
instance?: string;

/**
* @description Problem type definitions MAY extend the problem details object with additional members.
*/
[key: string]: any;
}

/** Format attendu des erreurs JSON issues du serveur. */
export interface ErrorResponse extends ProblemDetail {}

/** Erreur JSON issue du serveur, à laquelle on a ajouté des infos issues du parsing. */
export interface ManagedErrorResponse {
[key: string]: any;
export interface ManagedErrorResponse extends ErrorResponse {
/** Erreurs détectées dans l'erreur serveur. */
$parsedErrors: {
/** Erreurs globales. */
Expand All @@ -32,3 +69,18 @@ export function manageResponseErrors($status: number, response: ErrorResponse):
}
};
}

/**
* Parse une réponse du serveur pour enregistrer les erreurs.
* @param $status Statut HTTP de la réponse.
* @param response Corps de la réponse.
*/
export function manageProblemDetail(response: ProblemDetail): ManagedErrorResponse {
return {
...response,
$status: response.status,
$parsedErrors: {
globals: messageStore.addMessages(response)
}
};
}
5 changes: 4 additions & 1 deletion packages/core/src/network/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {isObject, merge, toPairs} from "lodash";

import {config} from "../utils";

import {ManagedErrorResponse, manageResponseErrors} from "./error-parsing";
import {ManagedErrorResponse, manageProblemDetail, manageResponseErrors} from "./error-parsing";
import {HttpMethod, requestStore} from "./store";

/**
Expand Down Expand Up @@ -77,6 +77,9 @@ export async function coreFetch(
return await Promise.reject<ManagedErrorResponse>(
manageResponseErrors(response.status, await response.json())
);
} else if (contentType?.includes("application/problem+json")) {
// Pour une erreur JSON, on la parse pour trouver et enregistrer les erreurs "attendues".
return await Promise.reject<ManagedErrorResponse>(manageProblemDetail(await response.json()));
} else {
// Sinon, on renvoie le body de la réponse sous format texte (faute de mieux).
console.error(`Une erreur ${response.status} est survenue lors de l'appel à "${url}".`);
Expand Down

0 comments on commit dd62cf9

Please sign in to comment.