Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Localize error messages #572

Merged
merged 3 commits into from
Sep 23, 2024
Merged

Localize error messages #572

merged 3 commits into from
Sep 23, 2024

Conversation

palagdan
Copy link
Collaborator

Resolves partially #550

@blcham blcham force-pushed the 550-error-message-id branch from dcf6eb8 to f848fff Compare August 30, 2024 14:48
@palagdan
Copy link
Collaborator Author

palagdan commented Sep 6, 2024

@blcham
I can't localize all the errors from the backend because many errors are dynamically generated. So, I replaced only errors with plain text, that does not contains some value from the backend.

@palagdan palagdan force-pushed the 550-error-message-id branch from 3347965 to 54472e4 Compare September 12, 2024 12:55
@palagdan palagdan requested a review from blcham September 12, 2024 12:55
@palagdan palagdan force-pushed the 550-error-message-id branch from 54472e4 to b1ddee9 Compare September 12, 2024 13:05
Copy link
Contributor

@blcham blcham left a comment

Choose a reason for hiding this comment

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

@palagdan @kostobog What do you think about the following? (

I see a lot of duplicate text, so I am thinking if it is not better to have some .error.genericError as a template (using i18next nesting -- https://www.i18next.com/translation-function/nesting):

{
  "error": {
    "default": "Došlo k chybě",
    "genericError": "Nepodařilo se {{action}} {{object}}. {{error}}",
    "faultEvent": {
      "findAll": "{{t('error.genericError', { action: 'najít', object: 'události závad' })}}",
      "update": "{{t('error.genericError', { action: 'aktualizovat', object: 'událost závady' })}}",
      "remove": "{{t('error.genericError', { action: 'odstranit', object: 'událost závady' })}}",
      "create": "{{t('error.genericError', { action: 'vytvořit', object: 'událost závady' })}}",
      "updateRectangle": "{{t('error.genericError', { action: 'aktualizovat', object: 'obdélník' })}}",
      "getFailureMode": "{{t('error.genericError', { action: 'načíst', object: 'režim selhání události' })}}",
      "deleteFailureMode": "{{t('error.genericError', { action: 'smazat', object: 'režim selhání události' })}}",
      "updateChildrenSequence": "{{t('error.genericError', { action: 'aktualizovat', object: 'pořadí dětí' })}}",
      "getRootReusable": "{{t('error.genericError', { action: 'najít', object: 'znovu použitelné události závady' })}}",
      "getAllReusable": "{{t('error.genericError', { action: 'najít', object: 'všechny znovu použitelné události závady' })}}"
    },
    "faultTree": {
      "rootEvent": {
        "deleteViolation": "Kořenová událost stromu nemůže být smazána!"
      },
      "intermediateEventAsLeaf": "Mezilehlá událost nemůže být na konci cesty!",
      "findAll": "{{t('error.genericError', { action: 'načíst', object: 'stromy závad' })}}",
      "findAllWithFilters": "{{t('error.genericError', { action: 'načíst', object: 'stromy závad s filtry' })}}",
      "find": "{{t('error.genericError', { action: 'najít', object: 'strom závad' })}}",
      "create": "{{t('error.genericError', { action: 'vytvořit', object: 'strom závad' })}}",
      "update": "{{t('error.genericError', { action: 'aktualizovat', object: 'strom závad' })}}",
      "remove": "{{t('error.genericError', { action: 'odstranit', object: 'strom závad' })}}",
      "getTreePaths": "{{t('error.genericError', { action: 'načíst', object: 'cesty stromu' })}}",
      "getTreePathsAggregate": "{{t('error.genericError', { action: 'načíst', object: 'všechny cesty stromu' })}}",
      "calculateCutSets": "{{t('error.genericError', { action: 'vypočítat', object: 'řezové množiny stromu závad' })}}"
    },

or having

  1. or having just a generic entity error
{
  "error": {
    "default": "Došlo k chybě",
    "entity": {
      "findAll": "Nepodařilo se načíst {{entity}}. {{error}}",
      "find": "Nepodařilo se najít {{entity}}. {{error}}",
      "create": "Nepodařilo se vytvořit {{entity}}. {{error}}",
      "update": "Nepodařilo se aktualizovat {{entity}}. {{error}}",
      "remove": "Nepodařilo se odstranit {{entity}}. {{error}}"
    },

@kostobog
Copy link
Collaborator

@blcham
When we optimize the text there will be grammar issues and it will be harder to maintain by translators.
Variant 2 is nice as it is compact but we should consider that it will be needed to refactor error codes for generic entity errors and also introduce a entity type argument in responseUtis.handleServerError.

@blcham
Copy link
Contributor

blcham commented Sep 13, 2024

ad 1)

When we optimize the text there will be grammar issues and it will be harder to maintain by translators.

I was not able to find any grammar issue although i do not like it much either.

ad 2)

we can discuss on the meeting.

@palagdan
Copy link
Collaborator Author

@blcham

I wanted to discuss one more thing. How should we handle dynamic exception messages like the following with messageId:

public class EntityNotFoundException extends FtaFmeaException {

    public EntityNotFoundException(String message) {
        super(message);
    }

    public static EntityNotFoundException create(String resourceName, Object identifier) {
        return new EntityNotFoundException(resourceName + " identified by " + identifier + " not found.");
    }

}

@blcham blcham force-pushed the 550-error-message-id branch 2 times, most recently from 8d34853 to 765031e Compare September 13, 2024 12:33
@kostobog
Copy link
Collaborator

@palagdan @blcham
Idea for question in comment
The server can send the arguments for a parametrized error message. For example:

public class ErrorInfo {
    private String message;
    private String messageId;
    private Map<String, String> messageArguments;
    private String requestUri;
}

For the example above, consider that server sends messageArguments as follows:

{ 
  resourceName: "Component"
  identifier: "component-id"
}

Message template can be declared as follows
"errorId": " {{resourceName}} identified by {{identifier}} not found."

And specific message can be constructed as:
t(data.messageId, data.messageArguments)

@palagdan palagdan force-pushed the 550-error-message-id branch from 765031e to a2715f0 Compare September 16, 2024 20:29
@palagdan
Copy link
Collaborator Author

@blcham

Thanks for the tip @kostobog regarding the arguments! I've implemented it on the backend—could you take a look? I've tested these errors, and now they are localized in Czech too:

Screenshot from 2024-09-17 13-16-40
Screenshot from 2024-09-17 13-18-21
Screenshot from 2024-09-17 14-08-25
Screenshot from 2024-09-17 22-12-49

@blcham blcham force-pushed the 550-error-message-id branch from ffff763 to 6737c05 Compare September 23, 2024 15:46
@blcham blcham merged commit 9470ccb into main Sep 23, 2024
1 check passed
@blcham blcham deleted the 550-error-message-id branch September 23, 2024 16:23
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.

3 participants