Skip to content

Commit f656f64

Browse files
committed
WEB-862: Localise the error as per the selected language
1 parent f6cfda8 commit f656f64

File tree

14 files changed

+168
-23
lines changed

14 files changed

+168
-23
lines changed

src/app/core/http/error-handler.interceptor.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { Injectable, inject } from '@angular/core';
1111
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http';
1212

1313
/** rxjs Imports */
14-
import { EMPTY, Observable } from 'rxjs';
14+
import { Observable } from 'rxjs';
1515
import { catchError } from 'rxjs/operators';
1616

1717
/** Environment Configuration */
@@ -63,9 +63,9 @@ export class ErrorHandlerInterceptor implements HttpInterceptor {
6363
globalisationCode = response.error.userMessageGlobalisationCode;
6464
}
6565

66-
// If we have a globalisation code, try to translate it
66+
// If we have a globalisation code, try to translate it with variable substitution
6767
if (globalisationCode) {
68-
const translated = this.translate.instant(globalisationCode);
68+
const translated = this.translate.instant(globalisationCode, response.error?.errors?.[0] || response.error || {});
6969
// Only use translation if the key actually exists (translate returns the key itself if not found)
7070
if (translated !== globalisationCode) {
7171
errorMessage = translated;
@@ -78,15 +78,22 @@ export class ErrorHandlerInterceptor implements HttpInterceptor {
7878
log.error(`Request Error: ${errorMessage}`);
7979
}
8080

81-
if (status === 401 || (environment.oauth.enabled && status === 400)) {
81+
// Check specific 403 error (invalid token) BEFORE generic 403 (higher priority)
82+
if (status === 403 && globalisationCode === 'error.token.invalid') {
83+
this.alertService.alert({
84+
type: this.translate.instant('error.token.invalid.type'),
85+
message: this.translate.instant('error.token.invalid.message')
86+
});
87+
} else if (status === 401) {
88+
// Allow Fineract translations for 401 errors
8289
this.alertService.alert({
8390
type: this.translate.instant('error.auth.type'),
84-
message: this.translate.instant('error.auth.message')
91+
message: errorMessage || this.translate.instant('error.auth.message')
8592
});
86-
} else if (status === 403 && errorMessage === 'The provided one time token is invalid') {
93+
} else if (environment.oauth.enabled && status === 400) {
8794
this.alertService.alert({
88-
type: this.translate.instant('error.token.invalid.type'),
89-
message: this.translate.instant('error.token.invalid.message')
95+
type: this.translate.instant('error.auth.type'),
96+
message: this.translate.instant('error.auth.message')
9097
});
9198
} else if (status === 400) {
9299
this.alertService.alert({
@@ -100,22 +107,28 @@ export class ErrorHandlerInterceptor implements HttpInterceptor {
100107
});
101108
} else if (status === 404) {
102109
if (isClientImage404) {
103-
return EMPTY;
110+
// Return observable of null for missing client images so imaging service can handle gracefully
111+
return new Observable((observer) => {
112+
observer.next(null);
113+
observer.complete();
114+
});
104115
} else {
105116
this.alertService.alert({
106-
type: this.translate.instant('error.resource.not.found'),
117+
type: this.translate.instant('error.resource.not.found.type'),
107118
message: errorMessage || this.translate.instant('error.resource.not.found.message')
108119
});
109120
}
110121
} else if (status === 500) {
122+
// Allow Fineract translations for 500 errors
111123
this.alertService.alert({
112124
type: this.translate.instant('error.server.internal.type'),
113-
message: this.translate.instant('error.server.internal.message')
125+
message: errorMessage || this.translate.instant('error.server.internal.message')
114126
});
115127
} else if (status === 501) {
128+
// Allow Fineract translations for 501 errors
116129
this.alertService.alert({
117130
type: this.translate.instant('error.resource.notImplemented.type'),
118-
message: this.translate.instant('error.resource.notImplemented.message')
131+
message: errorMessage || this.translate.instant('error.resource.notImplemented.message')
119132
});
120133
} else {
121134
this.alertService.alert({

src/assets/translations/cs-CS.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
"Remember me": "Zapamatuj si mě",
55
"error.resource.notImplemented.type": "Nenaimplementovaná chyba",
66
"error.resource.notImplemented.message": "Funkce není implementována!",
7+
"error.auth.type": "Chyba ověřování",
8+
"error.auth.message": "Neplatné údaje o uživateli. Zkuste prosím znovu!",
9+
"error.token.invalid.type": "Neplatný token",
10+
"error.token.invalid.message": "Neplatný token. Zkuste prosím znovu!",
11+
"error.bad.request.type": "Špatný požadavek",
12+
"error.bad.request.message": "V požadavku byly předány neplatné parametry!",
13+
"error.unauthorized.type": "Neautorizovaný požadavek",
14+
"error.unauthorized.message": "Nemáte oprávnění pro tento požadavek!",
15+
"error.resource.not.found.type": "Zdroj nenalezen",
16+
"error.resource.not.found.message": "Zdroj neexistuje!",
17+
"error.server.internal.type": "Interní chyba serveru",
18+
"error.server.internal.message": "Interní chyba serveru. Zkuste prosím později.",
19+
"error.unknown.type": "Neznámá chyba",
20+
"error.unknown.message": "Neznámá chyba. Zkuste prosím později.",
721
"errors": {
822
"accountingRule": {
923
"duplicateName": "Omlouváme se, ale účetní pravidlo s tímto názvem již existuje."

src/assets/translations/de-DE.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
"Remember me": "Erinnere dich an mich",
55
"error.resource.notImplemented.type": "Nicht implementierter Fehler",
66
"error.resource.notImplemented.message": "Nicht implementierte Funktion!",
7+
"error.auth.type": "Authentifizierungsfehler",
8+
"error.auth.message": "Ungültige Benutzerdetails. Bitte versuchen Sie es erneut!",
9+
"error.token.invalid.type": "Ungültiger Token",
10+
"error.token.invalid.message": "Ungültiger Token. Bitte versuchen Sie es erneut!",
11+
"error.bad.request.type": "Ungültige Anfrage",
12+
"error.bad.request.message": "Ungültige Parameter wurden in der Anfrage übergeben!",
13+
"error.unauthorized.type": "Unbefugte Anfrage",
14+
"error.unauthorized.message": "Sie sind nicht berechtigt für diese Anfrage!",
15+
"error.resource.not.found.type": "Ressource nicht gefunden",
16+
"error.resource.not.found.message": "Die Ressource existiert nicht!",
17+
"error.server.internal.type": "Interner Serverfehler",
18+
"error.server.internal.message": "Interner Serverfehler. Bitte versuchen Sie es später erneut.",
19+
"error.unknown.type": "Unbekannter Fehler",
20+
"error.unknown.message": "Unbekannter Fehler. Bitte versuchen Sie es später erneut.",
721
"errors": {
822
"accountingRule": {
923
"duplicateName": "Entschuldigung, aber eine Buchungsregel mit diesem Namen existiert bereits."

src/assets/translations/en-US.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"error.bad.request.message": "Invalid parameters were passed in the request!",
1313
"error.unauthorized.type": "Unauthorized Request",
1414
"error.unauthorized.message": "You are not authorized for this request!",
15-
"error.resource.not.found": "Resource Not Found",
15+
"error.resource.not.found.type": "Resource Not Found",
1616
"error.resource.not.found.message": "Resource does not exist!",
1717
"error.server.internal.type": "Internal Server Error",
1818
"error.server.internal.message": "Internal Server Error. Please try again later.",

src/assets/translations/es-CL.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"error.bad.request.message": "Se enviaron parámetros no válidos en la solicitud.",
1717
"error.unauthorized.type": "Solicitud no autorizada",
1818
"error.unauthorized.message": "No está autorizado para esta solicitud.",
19-
"error.resource.not.found": "Recurso no encontrado",
19+
"error.resource.not.found.type": "Recurso no encontrado",
2020
"error.resource.not.found.message": "¡El recurso no existe!",
2121
"error.server.internal.type": "Error interno del servidor",
2222
"error.server.internal.message": "Error interno del servidor. Por favor, inténtelo más tarde.",

src/assets/translations/es-MX.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"error.bad.request.message": "Se enviaron parámetros no válidos en la solicitud.",
1717
"error.unauthorized.type": "Solicitud no autorizada",
1818
"error.unauthorized.message": "No está autorizado para esta solicitud.",
19-
"error.resource.not.found": "Recurso no encontrado",
19+
"error.resource.not.found.type": "Recurso no encontrado",
2020
"error.resource.not.found.message": "¡El recurso no existe!",
2121
"error.server.internal.type": "Error interno del servidor",
2222
"error.server.internal.message": "Error interno del servidor. Por favor, inténtelo más tarde.",

src/assets/translations/fr-FR.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,20 @@
88
},
99
"error.resource.notImplemented.type": "Erreur non implémentée",
1010
"error.resource.notImplemented.message": "Fonctionnalité non implémentée !",
11-
"linkedSavingsAccountOwnership": "Le compte d'épargne lié n'appartient pas au client sélectionné.",
11+
"error.auth.type": "Erreur d'authentification",
12+
"error.auth.message": "Détails utilisateur invalides. Veuillez réessayer!",
13+
"error.token.invalid.type": "Token invalide",
14+
"error.token.invalid.message": "Token invalide. Veuillez réessayer!",
15+
"error.bad.request.type": "Mauvaise demande",
16+
"error.bad.request.message": "Des paramètres invalides ont été transmis dans la demande!",
17+
"error.unauthorized.type": "Demande non autorisée",
18+
"error.unauthorized.message": "Vous n'êtes pas autorisé pour cette demande!",
19+
"error.resource.not.found.type": "Ressource non trouvée",
20+
"error.resource.not.found.message": "La ressource n'existe pas!",
21+
"error.server.internal.type": "Erreur interne du serveur",
22+
"error.server.internal.message": "Erreur interne du serveur. Veuillez réessayer plus tard.",
23+
"error.unknown.type": "Erreur inconnue",
24+
"error.unknown.message": "Erreur inconnue. Veuillez réessayer plus tard.",
1225
"clientNotInGSIM": "Le client avec l'ID {{id}} n'est pas membre du GSIM.",
1326
"Capitalized Income amount adjusted already adjusted": "Montant du revenu capitalisé ajusté déjà ajusté",
1427
"Capitalized Income Adjustment amount must be lower or equal to": "Le montant de l'ajustement du revenu capitalisé doit être inférieur ou égal à",

src/assets/translations/it-IT.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,20 @@
88
},
99
"error.resource.notImplemented.type": "Errore non implementato",
1010
"error.resource.notImplemented.message": "Funzionalità non implementata!",
11-
"linkedSavingsAccountOwnership": "Il conto di risparmio collegato non appartiene al cliente selezionato.",
11+
"error.auth.type": "Errore di autenticazione",
12+
"error.auth.message": "Dettagli utente non validi. Per favore riprova!",
13+
"error.token.invalid.type": "Token non valido",
14+
"error.token.invalid.message": "Token non valido. Per favore riprova!",
15+
"error.bad.request.type": "Richiesta non valida",
16+
"error.bad.request.message": "Parametri non validi sono stati trasmessi nella richiesta!",
17+
"error.unauthorized.type": "Richiesta non autorizzata",
18+
"error.unauthorized.message": "Non sei autorizzato per questa richiesta!",
19+
"error.resource.not.found.type": "Risorsa non trovata",
20+
"error.resource.not.found.message": "La risorsa non esiste!",
21+
"error.server.internal.type": "Errore interno del server",
22+
"error.server.internal.message": "Errore interno del server. Per favore riprova più tardi.",
23+
"error.unknown.type": "Errore sconosciuto",
24+
"error.unknown.message": "Errore sconosciuto. Per favore riprova più tardi.",
1225
"clientNotInGSIM": "Il cliente con ID {{id}} non è presente in GSIM.",
1326
"Capitalized Income amount adjusted already adjusted": "Importo del reddito capitalizzato rettificato già rettificato",
1427
"Capitalized Income Adjustment amount must be lower or equal to": "L'importo dell'adeguamento del reddito capitalizzato deve essere inferiore o uguale a",

src/assets/translations/ko-KO.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,20 @@
88
},
99
"error.resource.notImplemented.type": "구현되지 않은 오류",
1010
"error.resource.notImplemented.message": "구현되지 않은 기능입니다!",
11-
"linkedSavingsAccountOwnership": "연결된 저축 계좌가 선택한 클라이언트에 속하지 않습니다.",
11+
"error.auth.type": "인증 오류",
12+
"error.auth.message": "잘못된 사용자 세부정보입니다. 다시 시도해주세요!",
13+
"error.token.invalid.type": "유효하지 않은 토큰",
14+
"error.token.invalid.message": "유효하지 않은 토큰입니다. 다시 시도해주세요!",
15+
"error.bad.request.type": "잘못된 요청",
16+
"error.bad.request.message": "요청에 잘못된 매개변수가 전달되었습니다!",
17+
"error.unauthorized.type": "승인되지 않은 요청",
18+
"error.unauthorized.message": "이 요청에 대해 권한이 없습니다!",
19+
"error.resource.not.found.type": "리소스를 찾을 수 없음",
20+
"error.resource.not.found.message": "리소스가 존재하지 않습니다!",
21+
"error.server.internal.type": "내부 서버 오류",
22+
"error.server.internal.message": "내부 서버 오류입니다. 나중에 다시 시도해주세요.",
23+
"error.unknown.type": "알 수 없는 오류",
24+
"error.unknown.message": "알 수 없는 오류입니다. 나중에 다시 시도해주세요.",
1225
"clientNotInGSIM": "ID가 {{id}}인 클라이언트가 GSIM에 없습니다.",
1326
"Capitalized Income amount adjusted already adjusted": "자본화된 소득 금액은 이미 조정되었습니다.",
1427
"Capitalized Income Adjustment amount must be lower or equal to": "자본화된 소득 조정 금액은 다음보다 낮거나 같아야 합니다.",

src/assets/translations/lt-LT.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,20 @@
88
},
99
"error.resource.notImplemented.type": "Neįdiegta klaida",
1010
"error.resource.notImplemented.message": "Funkcionalumas neįdiegtas!",
11-
"linkedSavingsAccountOwnership": "Susieta taupomoji sąskaita nepriklauso pasirinktam klientui.",
11+
"error.auth.type": "Autentifikavimo klaida",
12+
"error.auth.message": "Neteisingi vartotojo duomenys. Bandykite dar kartą!",
13+
"error.token.invalid.type": "Nevalidus žeton",
14+
"error.token.invalid.message": "Nevalidus žeton. Bandykite dar kartą!",
15+
"error.bad.request.type": "Bloga užklausa",
16+
"error.bad.request.message": "Užklausoje buvo perduoti neteisingi parametrai!",
17+
"error.unauthorized.type": "Neleistina užklausa",
18+
"error.unauthorized.message": "Jūs neturite leidimo šiai užklausai!",
19+
"error.resource.not.found.type": "Išteklius nerastas",
20+
"error.resource.not.found.message": "Išteklius neegzistuoja!",
21+
"error.server.internal.type": "Vidinė serverio klaida",
22+
"error.server.internal.message": "Vidinė serverio klaida. Bandykite dar kartą vėliau.",
23+
"error.unknown.type": "Nežinoma klaida",
24+
"error.unknown.message": "Nežinoma klaida. Bandykite dar kartą vėliau.",
1225
"clientNotInGSIM": "Klientas su ID {{id}} nėra GSIM sistemoje.",
1326
"Capitalized Income amount adjusted already adjusted": "Kapitalizuotų pajamų suma pakoreguota jau pakoreguota",
1427
"Capitalized Income Adjustment amount must be lower or equal to": "Kapitalizuotų pajamų koregavimo suma turi būti mažesnė arba lygi",

0 commit comments

Comments
 (0)