Files
parenthese/frontend/src/utils/errorMessages.js
T

203 lines
6.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { t } from '../i18n/index.js'
export function getShareErrorMessage(error) {
if (error?.status === 401) {
return t('Mot de passe invalide ou accès expiré.')
}
if (error?.status === 404) {
return t('Arbre introuvable.')
}
if (error?.status === 429) {
return t('Trop de tentatives. Réessayez dans une minute.')
}
return t('Connexion backend impossible. Vérifiez API/DB puis réessayez.')
}
export function getAccountDeletionErrorMessage(error, confirmation = {}) {
// Compte sans mot de passe (connexion OIDC) : l'email retapé, et une connexion récente chez le fournisseur
if (error?.payload?.error === 'recent_sign_in_required') {
return t('Pour supprimer le compte, reconnectez-vous avec votre fournisseur de connexion, puis recommencez dans le quart d’heure.')
}
if (error?.status === 403 && confirmation.confirmEmail !== undefined) {
return t("Cette adresse n'est pas celle du compte.")
}
if (error?.status === 403) {
return t('Mot de passe incorrect.')
}
if (error?.status === 401) {
return t('Session expirée. Reconnectez-vous puis réessayez.')
}
if (error?.status === 400) {
return t('Saisissez votre mot de passe actuel.')
}
if (error?.status === 429) {
return t('Trop de tentatives. Réessayez dans une minute.')
}
return t('Impossible de supprimer le compte pour le moment. Réessayez plus tard.')
}
export function getAccountErrorMessage(error) {
const errorCode = error?.payload?.error || error?.message || ''
if (errorCode === 'image_too_large') {
return t('Image trop volumineuse (maximum 5 Mo).')
}
if (errorCode === 'invalid_avatar_mime_type') {
return t("Format d'avatar invalide. Utilisez une image.")
}
if (errorCode === 'size_mismatch' || errorCode === 'invalid_base64_data' || errorCode === 'empty_media_file') {
return t('Le fichier média envoyé est invalide.')
}
if (errorCode === 'invalid_media_mime_type') {
return t('Le format de fichier ne correspond pas au type de média choisi.')
}
if (errorCode === 'storage_quota_exceeded') {
return t("L'arbre n'a plus de place pour de nouveaux souvenirs. Son propriétaire peut en supprimer.")
}
if (errorCode === 'password_login_disabled') {
return t('Sur cette instance, la connexion passe par le bouton du fournisseur.')
}
if (errorCode === 'oidc_email_unverified') {
return t("Votre fournisseur de connexion n'indique pas que votre adresse email est vérifiée. Vérifiez-la chez lui, puis réessayez.")
}
if (errorCode === 'oidc_email_taken') {
return t("Un compte avec mot de passe existe déjà pour cette adresse. Connectez-vous avec votre email et votre mot de passe.")
}
if (errorCode === 'oidc_email_missing') {
return t("Votre fournisseur de connexion n'a pas donné d'adresse email. La personne qui héberge l'instance doit autoriser le partage de l'email.")
}
if (errorCode === 'oidc_unavailable') {
return t('Le fournisseur de connexion ne répond pas. Réessayez dans un moment.')
}
if (errorCode === 'oidc_failed' || errorCode === 'invalid_handoff') {
return t("La connexion n'a pas abouti. Réessayez.")
}
if (errorCode === 'registration_closed') {
return t("Cette instance n'accepte plus de nouveaux comptes. Demandez à la personne qui l'héberge.")
}
// Lien d'invitation à co-gérer un arbre (issue #145)
if (errorCode === 'invitation_email_mismatch') {
return t("Cette invitation est pour une autre adresse. Utilisez l'adresse à laquelle vous avez été invité.")
}
if (errorCode === 'invitation_invalid' || errorCode === 'invitation_used' || errorCode === 'invitation_expired') {
return t("Ce lien d'invitation ne marche plus. Demandez-en un nouveau à la personne qui vous a invité.")
}
if (errorCode === 'already_owner') {
return t('Vous êtes déjà propriétaire de cet arbre.')
}
if (errorCode === 'citation_text_required') {
return t('Ajoutez le texte de la citation.')
}
if (errorCode === 'database_error' || (error?.status === 500 && error?.payload?.error === 'database_error')) {
return t("Erreur base de données. Lancez `npm run prisma:deploy` puis redémarrez l'API.")
}
if (error?.status === 503 && error?.message === 'database_unavailable') {
return t('Base de données indisponible. Lancez `npm run db:bootstrap` dans le backend.')
}
if (error?.status === 400) {
if (error?.message === 'invalid_payload' || error?.payload?.error === 'invalid_payload') {
const fieldErrors = error?.payload?.details?.fieldErrors || {}
const formErrors = error?.payload?.details?.formErrors || []
if (fieldErrors.slug?.length) {
return t('Slug invalide : 3-64 caractères, uniquement lettres minuscules, chiffres et tirets.')
}
if (fieldErrors.name?.length) {
return t("Nom d'arbre invalide : entre 2 et 120 caractères.")
}
if (fieldErrors.visitorPassword?.length || fieldErrors.contributorPassword?.length) {
return t('Mots de passe invalides : entre 8 et 128 caractères.')
}
const firstField = Object.keys(fieldErrors)[0]
if (firstField && Array.isArray(fieldErrors[firstField]) && fieldErrors[firstField].length > 0) {
return `${firstField}: ${fieldErrors[firstField][0]}`
}
if (Array.isArray(formErrors) && formErrors.length > 0) {
return t('Erreur formulaire : {error}', { error: formErrors[0] })
}
}
return t('Données invalides. Vérifiez les champs.')
}
if (error?.status === 401) {
return t('Session invalide ou identifiants incorrects.')
}
if (error?.status === 403) {
return t('Accès refusé pour cet arbre.')
}
if (error?.status === 404) {
return t('Ressource introuvable.')
}
if (error?.status === 409) {
return t('Conflit détecté (email ou slug déjà utilisé).')
}
if (error?.status === 429) {
return t('Trop de tentatives. Réessayez dans une minute.')
}
return t("Erreur backend. Vérifiez que l'API et la base sont lancées.")
}
export function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
if (typeof reader.result !== 'string') {
reject(new Error('invalid_file_reader_result'))
return
}
const commaIndex = reader.result.indexOf(',')
if (commaIndex < 0) {
reject(new Error('invalid_data_url'))
return
}
resolve(reader.result.slice(commaIndex + 1))
}
reader.onerror = () => {
reject(reader.error || new Error('file_read_failed'))
}
reader.readAsDataURL(file)
})
}