Skip to content

WEB-860: Present the GlobalisationCode and translated it to the local languages as part of the message instead of the fixed value for errors#3396

Open
EDSONZ-WASSWA wants to merge 1 commit intoopenMF:devfrom
EDSONZ-WASSWA:WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages
Open

WEB-860: Present the GlobalisationCode and translated it to the local languages as part of the message instead of the fixed value for errors#3396
EDSONZ-WASSWA wants to merge 1 commit intoopenMF:devfrom
EDSONZ-WASSWA:WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages

Conversation

@EDSONZ-WASSWA
Copy link
Copy Markdown

@EDSONZ-WASSWA EDSONZ-WASSWA commented Mar 17, 2026

…uages as part of the message

Description

Before, the Mifos X Web App showed a generic message like “Unknown Error. Please try again later” whenever an API call failed. Even though Apache Fineract returned detailed error information, the UI ignored it, making it hard for users to understand what went wrong.

Now, the app extracts those backend error codes, translates them, and displays a clear, meaningful message. This makes errors easier to understand and much simpler to debug.

Related issues and discussion

#{Issue Number}
https://mifosforge.jira.com/issues?filter=-1&selectedIssue=WEB-860

Screenshots, if any

before
before-fix
After
Screenshot 2026-03-17 003225
Screenshot 2026-03-17 003249

please @IOhacker please have a look at this

Summary by CodeRabbit

  • Improvements

    • Error messages are translated and shown in the user’s language with clearer handling for authentication, authorization, not‑found, server, bad‑request, and other error types. Developer diagnostics are logged in non‑production; image‑not‑found cases for client assets are suppressed to avoid unnecessary alerts.
  • New Translation Strings

    • Added localized messages (“service unavailable”, “data type not supported”) across multiple languages (cs, de, en, es, fr, it, ko, lt, lv, ne, pt, sw).

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'pre_merge_checks'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

Adds translation-aware Fineract error parsing to error handling: new interfaces and translateFineractError in ErrorHandlerService; interceptor uses it to produce translated, deduplicated messages and updates status-to-alert logic; two translation keys added across 13 locale files. (48 words)

Changes

Cohort / File(s) Summary
Error handling service
src/app/core/error-handler/error-handler.service.ts
Adds exported interfaces FineractErrorDetail and FineractErrorResponse; injects TranslateService; adds translateFineractError(errorResponse) to parse top-level and nested Fineract errors, dedupe messages, and getMessageForCode(code, defaultMessage) fallback.
HTTP interceptor
src/app/core/http/error-handler.interceptor.ts
Injects and uses ErrorHandlerService to compute translated errorMessage from backend payloads; extracts developerMessage for non-prod logging; revises status-to-alert branches (400/401/403/404/500/default) to use new translated keys and improved invalid-token detection while preserving throw behavior and client-image 404 silencing.
Translation files
src/assets/translations/{cs-CS,de-DE,en-US,es-CL,es-MX,fr-FR,it-IT,ko-KO,lt-LT,lv-LV,ne-NE,pt-PT,sw-SW}.json
Adds two new translation keys in each locale: error.msg.platform.service.unavailable and error.msg.database.type.not.supported with localized messages.

Sequence Diagram

sequenceDiagram
    participant Client as Client/HTTP Request
    participant Interceptor as Error Interceptor
    participant ErrorService as ErrorHandlerService
    participant Translate as TranslateService
    participant Alert as AlertService

    Client->>Interceptor: receives HTTP Error Response
    Interceptor->>ErrorService: translateFineractError(errorBody)
    ErrorService->>ErrorService: parse top-level and nested errors, dedupe messages
    ErrorService->>Translate: instant(translationKey) or return defaultMessage
    Translate-->>ErrorService: translated strings
    ErrorService-->>Interceptor: translatedErrorMessage
    Interceptor->>Alert: show translatedErrorMessage (alert type based on status)
    Alert-->>Client: display error to user
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • IOhacker
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: extracting GlobalisationCode from backend errors, translating them to local languages, and displaying them as part of error messages instead of generic fixed values.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/app/core/error-handler/error-handler.service.ts (1)

200-235: Replace any with a typed Fineract error contract.

The new translator path sits on core error handling; using any here reduces safety and propagates weak typing downstream.

♻️ Suggested typed refactor
+interface FineractErrorItem {
+  userMessageGlobalisationCode?: string;
+  defaultUserMessage?: string;
+}
+
+interface FineractErrorResponse extends FineractErrorItem {
+  errors?: FineractErrorItem[];
+}
+
-  translateFineractError(errorResponse: any): string {
+  translateFineractError(errorResponse: FineractErrorResponse | null | undefined): string {
     if (!errorResponse || typeof errorResponse !== 'object') {
       return '';
     }
@@
-    if (Array.isArray(errorResponse.errors)) {
-      errorResponse.errors.forEach((error: any) => {
+    if (Array.isArray(errorResponse.errors)) {
+      errorResponse.errors.forEach((error: FineractErrorItem) => {
         if (!error || typeof error !== 'object') {
           return;
         }

Based on learnings: “In TypeScript files … introduce specific interfaces/types for the response shapes and use proper typing instead of any.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/core/error-handler/error-handler.service.ts` around lines 200 - 235,
translateFineractError currently accepts untyped errorResponse and uses any for
nested errors; define a FineractErrorResponse interface (fields:
userMessageGlobalisationCode?: string, defaultUserMessage?: string, errors?:
FineractErrorDetail[]) and a FineractErrorDetail interface (same optional
fields) in this file or a shared types file, then change the function signature
to translateFineractError(errorResponse: FineractErrorResponse | null |
undefined) and update the forEach callback to use (error: FineractErrorDetail)
so all property accesses are type-checked while keeping the existing logic and
still calling getMessageForCode.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/core/http/error-handler.interceptor.ts`:
- Around line 50-55: The code currently includes errorBody.developerMessage in
the UI errorMessage; remove developerMessage from the user-facing message
assembly in error-handler.interceptor.ts and only surface translatedErrorMessage
or errorBody.defaultUserMessage (or response.message as final fallback) when
constructing errorMessage for UI. If developerMessage exists, ensure it's
recorded to logs only (e.g., send errorBody.developerMessage to the existing
logging path or errorHandlerService) rather than concatenating it into
errorMessage; keep translateFineractError(errorBody) and
errorBody.defaultUserMessage as the primary user-facing sources and log
developerMessage separately.
- Around line 90-93: Replace hardcoded English strings in the
ErrorHandlerInterceptor's alertService.alert calls with i18n lookups using
this.translate.instant; specifically change the alert type and message for
Internal Server Error to
this.translate.instant('error.resource.internalServerError.type') and
this.translate.instant('error.resource.internalServerError.message') (and apply
the same pattern to other status branches such as 401, 403, 400 and fallback 404
messages that currently use literal strings), updating the alertService.alert
invocations in the error-handler.interceptor (e.g., inside the handleError /
intercept branches) to use translate.instant keys, then run npm run
translations:extract to add the new keys to translation files.

In `@src/assets/translations/es-CL.json`:
- Line 6: Update the translation value for the key
"error.msg.database.type.not.supported" to use singular phrasing and include
terminal punctuation; locate that key in src/assets/translations/es-CL.json and
change the string from "El tipo de datos no es compatible" to a natural singular
form with a period at the end (e.g., "El tipo de dato no es compatible.").

In `@src/assets/translations/ne-NE.json`:
- Around line 5-6: The Nepali locale entries are written with Hindi-leaning
phrasing; update the two keys "error.msg.platform.service.unavailable" and
"error.msg.database.type.not.supported" to proper Nepali wording (e.g., use
phrases like "अनुरोध प्रस्तुत गर्न सक्षम छैन" / "कृपया केही समयपछि पुन: प्रयास
गर्नुहोस्" for the platform outage message and "डेटाबेस प्रकार समर्थन हुँदैन" or
"डेटाबेस प्रकार समर्थन गरिंदैन" for the unsupported DB message) so the ne-NE
file uses consistent Nepali phrasing instead of Hindi terms.

---

Nitpick comments:
In `@src/app/core/error-handler/error-handler.service.ts`:
- Around line 200-235: translateFineractError currently accepts untyped
errorResponse and uses any for nested errors; define a FineractErrorResponse
interface (fields: userMessageGlobalisationCode?: string, defaultUserMessage?:
string, errors?: FineractErrorDetail[]) and a FineractErrorDetail interface
(same optional fields) in this file or a shared types file, then change the
function signature to translateFineractError(errorResponse:
FineractErrorResponse | null | undefined) and update the forEach callback to use
(error: FineractErrorDetail) so all property accesses are type-checked while
keeping the existing logic and still calling getMessageForCode.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5aa5672b-efe1-48cc-a2e5-2e9a04cb022d

📥 Commits

Reviewing files that changed from the base of the PR and between 767c928 and ece690d.

📒 Files selected for processing (15)
  • src/app/core/error-handler/error-handler.service.ts
  • src/app/core/http/error-handler.interceptor.ts
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json

Comment thread src/app/core/http/error-handler.interceptor.ts Outdated
Comment thread src/app/core/http/error-handler.interceptor.ts
Comment thread src/assets/translations/es-CL.json Outdated
Comment thread src/assets/translations/ne-NE.json Outdated
@EDSONZ-WASSWA EDSONZ-WASSWA force-pushed the WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages branch from ece690d to 908d688 Compare March 17, 2026 09:14
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/core/http/error-handler.interceptor.ts`:
- Around line 69-73: The branch that detects an invalid one-time token should
not rely on the localized `errorMessage` string; update the conditional in
error-handler.interceptor (the block using `status === 403` and `errorMessage
=== 'The provided one time token is invalid'`) to instead check for a stable
backend identifier such as `body.userMessageGlobalisationCode` (or
`body.defaultUserMessage` as a fallback) before calling
`this.alertService.alert(...)`; ensure you still handle the case where those
fields are absent by falling back to the existing localized `errorMessage` check
only as last resort so non-English sessions route correctly.
- Around line 97-105: The current 500/501 branches call alertService.alert with
only the generic translate.instant messages, dropping the already-computed
translated backend detail (errorMessage) created earlier (see the errorMessage
computation). Update the 500 and 501 branches in error-handler.interceptor.ts so
that alertService.alert still uses the translated title via
translate.instant(...) for type but uses the computed errorMessage (or falls
back to the generic translate.instant message) for message; reference the
alertService.alert calls, the translate.instant invocations, and the
errorMessage variable to locate and adjust the logic accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6a2abf84-9834-411d-9a2a-51292045d180

📥 Commits

Reviewing files that changed from the base of the PR and between ece690d and 908d688.

📒 Files selected for processing (15)
  • src/app/core/error-handler/error-handler.service.ts
  • src/app/core/http/error-handler.interceptor.ts
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/ne-NE.json
  • src/app/core/error-handler/error-handler.service.ts

Comment thread src/app/core/http/error-handler.interceptor.ts Outdated
Comment thread src/app/core/http/error-handler.interceptor.ts
@IOhacker
Copy link
Copy Markdown
Contributor

Which is the ticket?

@EDSONZ-WASSWA
Copy link
Copy Markdown
Author

Copy link
Copy Markdown
Contributor

@IOhacker IOhacker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EDSONZ-WASSWA please change the title of the PR as "WEB-860: Present the GlobalisationCode and translated it to the local languages as part of the message instead of the fixed value for errors"

@EDSONZ-WASSWA EDSONZ-WASSWA changed the title fix-Present the GlobalisationCode and translated it to the local lang… fix-"WEB-860: Present the GlobalisationCode and translated it to the local languages as part of the message instead of the fixed value for errors Mar 17, 2026
@EDSONZ-WASSWA EDSONZ-WASSWA requested a review from IOhacker March 17, 2026 22:45
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/assets/translations/ko-KO.json`:
- Around line 5-6: This file fails the project's Prettier formatting check; run
the formatter (e.g., npx prettier --write .) to normalize spacing, trailing
commas/newline and overall JSON style so the translations remain valid for
ErrorHandlerService.getMessageForCode() lookups; after formatting, verify the
JSON still contains the keys "error.msg.platform.service.unavailable" and
"error.msg.database.type.not.supported" at the root and commit the formatted
file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aa323809-3c28-48d2-9f3d-2ba8827640db

📥 Commits

Reviewing files that changed from the base of the PR and between 908d688 and 8071ddd.

📒 Files selected for processing (13)
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/cs-CS.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/en-US.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/sw-SW.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/es-CL.json

Comment thread src/assets/translations/ko-KO.json
@EDSONZ-WASSWA EDSONZ-WASSWA force-pushed the WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages branch from 8071ddd to a8fe562 Compare March 18, 2026 08:56
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/app/core/http/error-handler.interceptor.ts (1)

105-114: ⚠️ Potential issue | 🟠 Major

500/501 branches still drop translated backend detail.

These branches always show generic text and ignore the computed errorMessage, which can regress the detailed translated-error behavior introduced by this PR.

💡 Proposed fix
     } else if (status === 500) {
       this.alertService.alert({
         type: this.translate.instant('error.resource.internalServerError.type'),
-        message: this.translate.instant('error.resource.internalServerError.message')
+        message: errorMessage || this.translate.instant('error.resource.internalServerError.message')
       });
     } else if (status === 501) {
       this.alertService.alert({
         type: this.translate.instant('error.resource.notImplemented.type'),
-        message: this.translate.instant('error.resource.notImplemented.message')
+        message: errorMessage || this.translate.instant('error.resource.notImplemented.message')
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/core/http/error-handler.interceptor.ts` around lines 105 - 114, The
500 and 501 branches in the error handler (the status === 500 and status === 501
blocks) always set the alert message to a generic translate.instant string and
ignore the previously computed errorMessage; update those branches in
handleError/error-handler.interceptor to use the computed errorMessage (or
combine the translated fallback with errorMessage) when calling
alertService.alert so translated backend details are preserved (keep using
translate.instant for the type field).
🧹 Nitpick comments (1)
src/app/core/http/error-handler.interceptor.ts (1)

50-53: Add developerMessage to the FineractErrorResponse interface and remove the any type annotation.

The errorBody variable uses any type, which bypasses strict typing. The code accesses developerMessage (line 52) and defaultUserMessage (line 53), but the FineractErrorResponse interface only includes defaultUserMessage, not developerMessage. This gap should be fixed at the interface definition level rather than with a workaround.

Update FineractErrorResponse in src/app/core/error-handler/error-handler.service.ts to include the missing property:

export interface FineractErrorResponse {
  userMessageGlobalisationCode?: string;
  defaultUserMessage?: string;
  developerMessage?: string;
  errors?: FineractErrorDetail[];
}

Then change line 50 from const errorBody: any = response.error; to const errorBody: FineractErrorResponse | null = response.error || null;

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/core/http/error-handler.interceptor.ts` around lines 50 - 53, Update
the FineractErrorResponse type and stop using any for errorBody: add
developerMessage?: string to the FineractErrorResponse interface in
error-handler.service.ts (keeping existing userMessageGlobalisationCode?,
defaultUserMessage?, errors?: FineractErrorDetail[]), then in
error-handler.interceptor.ts change the errorBody declaration to be typed as
FineractErrorResponse | null (e.g., const errorBody: FineractErrorResponse |
null = response.error || null) so developerMessage and defaultUserMessage are
strongly typed when accessed by translateFineractError and the subsequent
developerMessage/errorMessage logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/app/core/http/error-handler.interceptor.ts`:
- Around line 105-114: The 500 and 501 branches in the error handler (the status
=== 500 and status === 501 blocks) always set the alert message to a generic
translate.instant string and ignore the previously computed errorMessage; update
those branches in handleError/error-handler.interceptor to use the computed
errorMessage (or combine the translated fallback with errorMessage) when calling
alertService.alert so translated backend details are preserved (keep using
translate.instant for the type field).

---

Nitpick comments:
In `@src/app/core/http/error-handler.interceptor.ts`:
- Around line 50-53: Update the FineractErrorResponse type and stop using any
for errorBody: add developerMessage?: string to the FineractErrorResponse
interface in error-handler.service.ts (keeping existing
userMessageGlobalisationCode?, defaultUserMessage?, errors?:
FineractErrorDetail[]), then in error-handler.interceptor.ts change the
errorBody declaration to be typed as FineractErrorResponse | null (e.g., const
errorBody: FineractErrorResponse | null = response.error || null) so
developerMessage and defaultUserMessage are strongly typed when accessed by
translateFineractError and the subsequent developerMessage/errorMessage logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 66c2f2a6-f8c0-4238-ad83-2e054d1c2771

📥 Commits

Reviewing files that changed from the base of the PR and between 8071ddd and a8fe562.

📒 Files selected for processing (15)
  • src/app/core/error-handler/error-handler.service.ts
  • src/app/core/http/error-handler.interceptor.ts
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/cs-CS.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/ne-NE.json

@IOhacker IOhacker changed the title fix-"WEB-860: Present the GlobalisationCode and translated it to the local languages as part of the message instead of the fixed value for errors WEB-860: Present the GlobalisationCode and translated it to the local languages as part of the message instead of the fixed value for errors Mar 18, 2026
@saksham869
Copy link
Copy Markdown
Contributor

@EDSONZ-WASSWA I've resolved the merge conflicts with upstream/dev. To apply the fix to your PR branch,
run:

git fetch https://github.com/saksham869/web-app.git WEB-860-help
git checkout WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages
git reset --hard FETCH_HEAD
git push --force-with-lease origin WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages

What was resolved:
error-handler.service.ts — kept inject() pattern, unified translateService → translate, preserved translateFineractError() and getMessageForCode()
error-handler.interceptor.ts — added missing ErrorHandlerService import, kept WEB-862 translation keys and OTP check logic
All 13 locale files have both error.msg.platform.service.unavailable and error.msg.database.type.not.supported

Ready for re-review @IOhacker

@IOhacker
Copy link
Copy Markdown
Contributor

@EDSONZ-WASSWA could you please resolve the conflicts?

@EDSONZ-WASSWA
Copy link
Copy Markdown
Author

@EDSONZ-WASSWA could you please resolve the conflicts?

@IOhacker I have resolved them thankyou

@IOhacker
Copy link
Copy Markdown
Contributor

@EDSONZ-WASSWA plese squash and commit

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/app/core/http/error-handler.interceptor.ts (2)

90-121: ⚠️ Potential issue | 🔴 Critical

Fix merge-artifact corruption in the 401/400/403 condition chain—code is syntactically invalid.

Lines 91–94 have an unclosed alertService.alert() object. Line 95 incorrectly opens a new if (should be } else if) instead of continuing the control flow. The block also contains:

  • Duplicated status === 400 branches (lines 108 and 115)
  • Missing comma after the message property on line 118
  • Orphaned type and message properties on lines 119–120 without proper nesting

This appears to be a partial merge conflict where old i18n key conventions (e.g., error.resource.authenticationError.*) were not fully replaced with new ones (e.g., errors.error.auth.*). Consolidate the overlapping conditions and ensure all alert objects are properly closed.

Proposed normalized control flow
-    if (status === 401 || (environment.oauth.enabled && status === 400 && request.url.includes('/oauth/token'))) {
-      this.alertService.alert({
-        type: this.translate.instant('error.resource.authenticationError.type'),
-        message: this.translate.instant('error.resource.authenticationError.message')
-    if (status === 401 || (environment.oauth.enabled && status === 400)) {
-      this.alertService.alert({
-        type: this.translate.instant('errors.error.auth.type'),
-        message: this.translate.instant('errors.error.auth.message')
-      });
-    } else if (
-      status === 403 &&
-      response.error?.errors?.[0]?.defaultUserMessage === 'The provided one time token is invalid'
-    ) {
-      this.alertService.alert({
-        type: this.translate.instant('errors.error.token.invalid.type'),
-        message: this.translate.instant('errors.error.token.invalid.message')
-      });
-    } else if (status === 400) {
-      const fallback = this.translate.instant('errors.interceptor.invalidParams');
-      const message = parameterName ? `[${parameterName}] ${errorMessage || fallback}` : `${errorMessage || fallback}`;
-      this.alertService.alert({
-        type: this.translate.instant('errors.error.bad.request.type'),
-        message: message || this.translate.instant('errors.error.bad.request.message')
-      });
-    } else if (status === 400) {
+    if (status === 401 || (environment.oauth.enabled && status === 400 && request.url.includes('/oauth/token'))) {
+      this.alertService.alert({
+        type: this.translate.instant('error.resource.authenticationError.type'),
+        message: this.translate.instant('error.resource.authenticationError.message')
+      });
+    } else if (status === 400) {
       this.alertService.alert({
         type: this.translate.instant('error.resource.badRequest.type'),
         message: errorMessage || this.translate.instant('error.resource.badRequest.message')
-        type: this.translate.instant('errors.error.unauthorized.type'),
-        message: errorMessage || this.translate.instant('errors.error.unauthorized.message')
       });
     } else if (status === 403) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/core/http/error-handler.interceptor.ts` around lines 90 - 121, Fix
the merge-artifact in error-handler.interceptor.ts by repairing the malformed
control flow and alert objects: close the first this.alertService.alert({...})
call, change the stray `if (status === 401 || (environment.oauth.enabled &&
status === 400))` to `} else if (...)` to continue the chain, remove/merge the
duplicated `else if (status === 400)` branches into a single 400 handler that
uses `parameterName`/`errorMessage` and the correct i18n keys, add the missing
comma after the `message` property, and remove the orphaned `type`/`message`
lines; keep special-case checks for `environment.oauth.enabled &&
request.url.includes('/oauth/token')` and the 403 one-time-token check
(`response.error?.errors?.[0]?.defaultUserMessage`) intact, and ensure every
this.alertService.alert call is a well-formed object literal.

45-80: ⚠️ Potential issue | 🔴 Critical

Remove the duplicate errorMessage declaration and the legacy message-construction block; it violates TypeScript rules and can crash at runtime.

The declaration at line 47 (const errorMessage) is redeclared at line 69 (let errorMessage), which is a TypeScript compile-time error. The legacy block (lines 50–80) also contains unsafe .replace() calls on possibly undefined properties (defaultUserMessage and developerMessage), which will throw at runtime.

Additionally, the status-handling section (lines 90–169) contains merge artifacts with duplicate blocks and malformed object literals that prevent compilation. The 401, 400, 404, 500, and unknown error branches have duplicate keys and inconsistent i18n namespaces.

Replace the entire legacy block with the simplified approach relying on translatedErrorMessage from errorHandlerService, and clean up duplicate status branches to use consistent i18n keys and include errorMessage fallbacks where appropriate.

Key fixes needed
  1. Remove lines 50–80 (legacy top-level and nested message translation block)
  2. Consolidate duplicate status blocks (401, 400, 404, 500, unknown error)
  3. Ensure all error branches include errorMessage fallback where end-users need detail
  4. Replace any type on line 44 with a proper error interface for strict typing
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/core/http/error-handler.interceptor.ts` around lines 45 - 80, Remove
the legacy nested translation/message-construction block and the duplicate
errorMessage declaration; keep a single errorMessage variable populated from
translatedErrorMessage (from errorHandlerService.translateFineractError) or
fallback to response.error?.defaultUserMessage || response.message, and drop the
manual nested parsing using translate.instant and response.error.errors[0]. Also
remove unsafe .replace() calls on possibly undefined
defaultUserMessage/developerMessage and instead guard properties before
manipulating them (check existence of response.error.errors[0] and its fields).
Consolidate the duplicated status-handling branches (401, 400, 404, 500,
unknown) so each status uses consistent i18n keys and always includes the
errorMessage fallback for user-facing text, and replace the loose any type used
for the response/error with a strict interface (e.g., ErrorResponse) to enforce
safe property access and prevent redeclaration/merge issues.
♻️ Duplicate comments (1)
src/app/core/http/error-handler.interceptor.ts (1)

151-162: ⚠️ Potential issue | 🟠 Major

Keep translated backend detail for 500/501 alerts instead of always showing generic text.

Current 500/501 branches use generic messages only, which regresses the new detailed translated-error behavior.

Proposed fix
     } else if (status === 500) {
       this.alertService.alert({
         type: this.translate.instant('error.resource.internalServerError.type'),
-        message: this.translate.instant('error.resource.internalServerError.message')
+        message: errorMessage || this.translate.instant('error.resource.internalServerError.message')
       });
     } else if (status === 501) {
       this.alertService.alert({
-        type: this.translate.instant('errors.error.resource.notImplemented.type'),
-        message: this.translate.instant('errors.error.resource.notImplemented.message')
+        type: this.translate.instant('error.resource.notImplemented.type'),
+        message: errorMessage || this.translate.instant('error.resource.notImplemented.message')
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/core/http/error-handler.interceptor.ts` around lines 151 - 162, The
500/501 branches in error-handler.interceptor.ts currently replace detailed
backend translations with generic keys; update the status === 500 and status ===
501 branches to pass the backend-provided translated title/message into
this.alertService.alert (instead of always calling
this.translate.instant('errors.error.server.internal.*') or other generic keys).
Locate where the interceptor parses backend errors (the variable that holds
backend translation, e.g., parsedBackendError, translatedError, or
backendErrorTranslation) and use its title/message for the alert payload while
falling back to this.translate.instant(...) only if those backend fields are
missing; keep the calls to this.alertService.alert and this.translate.instant as
shown.
🧹 Nitpick comments (1)
src/app/core/http/error-handler.interceptor.ts (1)

44-44: Replace any with a typed error payload to preserve strict TypeScript safety.

const errorBody: any weakens checks around optional fields (developerMessage, errors, parameterName) and makes this method easier to break silently.

Typed payload example
+interface InterceptorErrorDetail {
+  userMessageGlobalisationCode?: string;
+  defaultUserMessage?: string;
+  developerMessage?: string;
+  parameterName?: string;
+}
+
+interface InterceptorErrorBody {
+  userMessageGlobalisationCode?: string;
+  defaultUserMessage?: string;
+  developerMessage?: string;
+  errors?: InterceptorErrorDetail[];
+}
...
-    const errorBody: any = response.error;
+    const errorBody: InterceptorErrorBody | undefined =
+      response.error && typeof response.error === 'object' ? (response.error as InterceptorErrorBody) : undefined;

As per coding guidelines: src/app/**/*.ts: Use TypeScript for all application code with strict typing conventions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/core/http/error-handler.interceptor.ts` at line 44, The line "const
errorBody: any = response.error" weakens TypeScript safety; define a strict
interface (e.g., ErrorPayload { developerMessage?: string; errors?:
Record<string,string[]>; parameterName?: string; [key: string]: unknown }) and
replace the any with that type, then cast or validate response.error into that
ErrorPayload before use in the interceptor method (where errorBody is
referenced) so optional fields are typed and checked rather than implicitly any.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/app/core/http/error-handler.interceptor.ts`:
- Around line 90-121: Fix the merge-artifact in error-handler.interceptor.ts by
repairing the malformed control flow and alert objects: close the first
this.alertService.alert({...}) call, change the stray `if (status === 401 ||
(environment.oauth.enabled && status === 400))` to `} else if (...)` to continue
the chain, remove/merge the duplicated `else if (status === 400)` branches into
a single 400 handler that uses `parameterName`/`errorMessage` and the correct
i18n keys, add the missing comma after the `message` property, and remove the
orphaned `type`/`message` lines; keep special-case checks for
`environment.oauth.enabled && request.url.includes('/oauth/token')` and the 403
one-time-token check (`response.error?.errors?.[0]?.defaultUserMessage`) intact,
and ensure every this.alertService.alert call is a well-formed object literal.
- Around line 45-80: Remove the legacy nested translation/message-construction
block and the duplicate errorMessage declaration; keep a single errorMessage
variable populated from translatedErrorMessage (from
errorHandlerService.translateFineractError) or fallback to
response.error?.defaultUserMessage || response.message, and drop the manual
nested parsing using translate.instant and response.error.errors[0]. Also remove
unsafe .replace() calls on possibly undefined
defaultUserMessage/developerMessage and instead guard properties before
manipulating them (check existence of response.error.errors[0] and its fields).
Consolidate the duplicated status-handling branches (401, 400, 404, 500,
unknown) so each status uses consistent i18n keys and always includes the
errorMessage fallback for user-facing text, and replace the loose any type used
for the response/error with a strict interface (e.g., ErrorResponse) to enforce
safe property access and prevent redeclaration/merge issues.

---

Duplicate comments:
In `@src/app/core/http/error-handler.interceptor.ts`:
- Around line 151-162: The 500/501 branches in error-handler.interceptor.ts
currently replace detailed backend translations with generic keys; update the
status === 500 and status === 501 branches to pass the backend-provided
translated title/message into this.alertService.alert (instead of always calling
this.translate.instant('errors.error.server.internal.*') or other generic keys).
Locate where the interceptor parses backend errors (the variable that holds
backend translation, e.g., parsedBackendError, translatedError, or
backendErrorTranslation) and use its title/message for the alert payload while
falling back to this.translate.instant(...) only if those backend fields are
missing; keep the calls to this.alertService.alert and this.translate.instant as
shown.

---

Nitpick comments:
In `@src/app/core/http/error-handler.interceptor.ts`:
- Line 44: The line "const errorBody: any = response.error" weakens TypeScript
safety; define a strict interface (e.g., ErrorPayload { developerMessage?:
string; errors?: Record<string,string[]>; parameterName?: string; [key: string]:
unknown }) and replace the any with that type, then cast or validate
response.error into that ErrorPayload before use in the interceptor method
(where errorBody is referenced) so optional fields are typed and checked rather
than implicitly any.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2f0c0847-1f95-4b39-80b4-5d7fb3b25929

📥 Commits

Reviewing files that changed from the base of the PR and between a8fe562 and 5864f57.

📒 Files selected for processing (2)
  • src/app/core/error-handler/error-handler.service.ts
  • src/app/core/http/error-handler.interceptor.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/core/error-handler/error-handler.service.ts

@EDSONZ-WASSWA
Copy link
Copy Markdown
Author

@EDSONZ-WASSWA I've resolved the merge conflicts with upstream/dev. To apply the fix to your PR branch, run:

git fetch https://github.com/saksham869/web-app.git WEB-860-help git checkout WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages git reset --hard FETCH_HEAD git push --force-with-lease origin WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages

What was resolved: error-handler.service.ts — kept inject() pattern, unified translateService → translate, preserved translateFineractError() and getMessageForCode() error-handler.interceptor.ts — added missing ErrorHandlerService import, kept WEB-862 translation keys and OTP check logic All 13 locale files have both error.msg.platform.service.unavailable and error.msg.database.type.not.supported

Ready for re-review @IOhacker

Hay @saksham869 I have fixed the merge conflicts

…guages (openMF#3385)

fix-Present the GlobalisationCode and translated it to the local languages as part of the message

	modified:   src/app/core/error-handler/error-handler.service.ts
	modified:   src/app/core/http/error-handler.interceptor.ts
@EDSONZ-WASSWA EDSONZ-WASSWA force-pushed the WEB-860-Present-the-GlobalisationCode-and-translated-it-to-the-local-languages branch from 5864f57 to edeab1e Compare April 16, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants