Skip to content

Conversation

@hebasto
Copy link
Member

@hebasto hebasto commented Feb 4, 2019

Ref: #16218

This PR:

  • makes GUI error messages bilingual: user's native language + untranslated (i.e. English)
  • insures that only untranslated messages are written to the debug log file and to stderr (that is not the case on master).

Screenshot from 2019-06-17 01-15-06

Note for reviewers: InitWarning() is out of this PR scope.

bool InitErrorFormat(const char* fmt, const Args&... args)
{
std::string original_message = strprintf(fmt, args...);
std::string translated_message = strprintf(_(fmt), args...);
Copy link
Member

Choose a reason for hiding this comment

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

I believe make translate wouldn't pick those up any more.

@hebasto hebasto force-pushed the 20190204-bilingual-initerror branch from ecd6197 to 0faa14c Compare February 4, 2019 15:41
@laanwj
Copy link
Member

laanwj commented Feb 4, 2019

This effectively removes all the translations as there is no _() to pick up anymore by gettext.

@DrahtBot
Copy link
Contributor

DrahtBot commented Feb 4, 2019

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #16194 (refactor: share blockmetadata with BlockManager by jamesob)
  • #16127 (Add support for thread safety annotations when using std::mutex by ajtowns)
  • #16112 (util: Log early messages by MarcoFalke)
  • #16003 (init: an incorrect amount of file descriptors is requested, and a different amount is also asserted by tryphe)
  • #15946 (Allow maintaining the blockfilterindex when using prune by jonasschnelli)
  • #15891 (test: Require standard txs in regtest by default by MarcoFalke)
  • #15848 (Add a check for free disk space at first startup. by darosior)
  • #15606 ([experimental] UTXO snapshots by jamesob)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@luke-jr
Copy link
Member

luke-jr commented Feb 4, 2019

This would be much easier to review if InitErrorFormat was named InitError...

@hebasto hebasto force-pushed the 20190204-bilingual-initerror branch from 0faa14c to 63b7018 Compare February 4, 2019 16:46
@hebasto
Copy link
Member Author

hebasto commented Feb 4, 2019

@MarcoFalke

I believe make translate wouldn't pick those up any more.

@laanwj

This effectively removes all the translations as there is no _() to pick up anymore by gettext.

Fixed.

The main goal of this PR is to avoid printing localized messages to the debug log file and stderr.
Bilingual GUI messages come for free.

@hebasto
Copy link
Member Author

hebasto commented Feb 4, 2019

@luke-jr

This would be much easier to review if InitErrorFormat was named InitError...

Rationale: InitErrorFormat can accept a format string as the first argument.

@hebasto hebasto closed this Feb 4, 2019
@jonasschnelli
Copy link
Contributor

I haven't looked at the code but printing error message always (additionally) in english seems to be a clever idea (especially with the faced complexity and immaturity of the UX).

@hebasto hebasto reopened this Feb 4, 2019
@hebasto hebasto force-pushed the 20190204-bilingual-initerror branch 3 times, most recently from 54c8d00 to fb394a6 Compare February 4, 2019 23:01
@fanquake fanquake added the GUI label Feb 4, 2019
@hebasto
Copy link
Member Author

hebasto commented Feb 4, 2019

@MarcoFalke @laanwj it works with gettext now.

@luke-jr your comment has been addressed.

@hebasto
Copy link
Member Author

hebasto commented Feb 4, 2019

Rebased.

src/init.cpp Outdated
if(!ECC_InitSanityCheck()) {
InitError("Elliptic curve cryptography sanity check failure. Aborting.");
if (!ECC_InitSanityCheck()) {
InitError(_("Elliptic curve cryptography sanity check failure. Aborting.", true));
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why this should be translated. This should never fail and if it fails, I bet you are better off with the english error message?

Copy link
Member

Choose a reason for hiding this comment

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

Agree, I feel we had this discussion already. Please don't translate extremely rare or technical errors.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

btw, this PR aims that a translated message:

  • is written to debug log in English
  • is printed to stderr in English
  • is shown in GUI in both languages

Therefore, english error message is always available even for translated messages.

src/init.cpp Outdated

if (!Random_SanityCheck()) {
InitError("OS cryptographic RNG sanity check failure. Aborting.");
InitError(_("OS cryptographic RNG sanity check failure. Aborting.", true));
Copy link
Member

Choose a reason for hiding this comment

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

Same for this one

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

}

ADD_SIGNALS_IMPL_WRAPPER(ThreadSafeMessageBox);
ADD_SIGNALS_IMPL_WRAPPER(ThreadSafeMessageBox2);
Copy link
Member

Choose a reason for hiding this comment

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

Please use a better name than ThreadSafeMessageBox2. What makes this function different?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

btw, 2 in ThreadSafeMessageBox2 meant "bi-" in bilingual rather "second" :)

@hebasto hebasto force-pushed the 20190204-bilingual-initerror branch from fb394a6 to 01781b4 Compare February 5, 2019 19:07
@hebasto
Copy link
Member Author

hebasto commented Feb 5, 2019

@MarcoFalke @laanwj
Thank you for your reviews. All your comments have been addressed.
Would you mind re-reviewing?

src/init.cpp Outdated

if (!SetupNetworking())
return InitError("Initializing networking failed");
return InitError(_("Initializing networking failed", true));
Copy link
Member

Choose a reason for hiding this comment

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

same here. This should never fail

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

@hebasto hebasto force-pushed the 20190204-bilingual-initerror branch from 01781b4 to 9a53d13 Compare February 5, 2019 20:00
@flack
Copy link
Contributor

flack commented Feb 8, 2019

If the point is to make it easier to google error messages, wouldn't it be more efficient to add some kind of error code to the output? E.g. the example from the screenshot could look like this in the English version:

ERR38278: Prune cannot be configured with a negative value

and like this in the German version:

ERR38278: Kürzungsmodus kann nicht mit einem negativen Wert konfiguriert werden

This would also help searchability if the English error text changes between versions. Only drawback I suppose is that somebody would have to come up with all the error codes :-)

@gmaxwell
Copy link
Contributor

I like the idea (so Concept ACK), no thoughts on the implementation.

@flack Trying to assign numerical error codes in the face of parallel development seems tricky... but not impossible.

The dual languages also helps in the common case that the user also reads English... since the translation may not be good or may not be clear (esp. even a native speaker of another language may have only seen various technical terms but a translator managed to use a rarely used word in the translated language). Error numbers don't have this benefit, so the dual language output would be useful independently of error numbers.

@flack
Copy link
Contributor

flack commented Feb 11, 2019

@gmaxwell yes, it would require some coordination. But I suppose a linter can take care of most of the problems, esp. since the numbers don't have to be consecutive or follow any kind of logic really.

It's true what you say about wonky translations. "Kürzungsmodus" from the screenshot is actually a case in point. It literally means "shortening mode". No way I would have guessed that this refers to pruning (or at least not on the first try). But otoh, if users have the UI set to e.g. German, then all they see are German terms, i.e. there's probably a checkbox labeled "Kürzungsmodus" somewhere and they might remember that they clicked that. Throwing the word "pruning" into the mix might just add to the confusion at this point, exactly because the meaning is different ("I selected shortening mode and now it's complaining about 'pruning' ?!?").

Anyhow, I get that my suggestion cannot be easily implemented in the short term, but how about making it a bit more clear that the two messages are actually referring to the same thing (instead of being one translated error and one untranslated error)? E.g. something like:

Kürzungsmodus kann nicht mit einem negativen Wert konfiguriert werden

Original-Meldung: Prune cannot be configured with a negative value

"Original-Meldung" means "original message". Could also say "untranslated message" or something.

@laanwj
Copy link
Member

laanwj commented Feb 12, 2019

since the translation may not be good or may not be clear

I think we need to be careful here also to respect the translators. They are not developers and will not understand internal technical details in error messages.

If an error message has more technical terms in it than the standard bitcoin and GUI ones such as window, wallet, block, transaction …. then it shouldn't be translated.

Translators will get pissed at me for this or substitute some nonsense word. In both cases no one is better off.

@flack
Copy link
Contributor

flack commented Feb 12, 2019

If an error message has more technical terms in it than the standard bitcoin and GUI ones such as window, wallet, block, transaction …. then it shouldn't be translated.

Still, you have to enable the user to make the connection between the error message and what they might have selected in the GUI settings. So e.g. if you don't translate "prune" in the error message, then you also shouldn't translate it in the rest of the GUI (or at least show the English term in brackets)

@laanwj
Copy link
Member

laanwj commented Feb 12, 2019

prune is a grey area I guess. It doesn't go with the obvious bitcoin or computer words but it also isn't something like "glibc sanity check failed" which makes no sense to users nor translators whatsoever.

So to be clear Im not against showing error messages in both languages, but this shouldn't a reason to translate things that would otherwise not be because the English message can be used to work around a terrible translation.

@hebasto hebasto force-pushed the 20190204-bilingual-initerror branch from 9a53d13 to 539950b Compare February 12, 2019 21:46
@hebasto
Copy link
Member Author

hebasto commented Feb 12, 2019

Rebased.

@DrahtBot
Copy link
Contributor

DrahtBot commented Mar 2, 2019

Needs rebase

@hebasto hebasto force-pushed the 20190204-bilingual-initerror branch from 539950b to 8aca2cf Compare June 16, 2019 22:06
@hebasto
Copy link
Member Author

hebasto commented Jun 16, 2019

Rebased after #15288 merged.

@flack your comment has been addressed.

OP and screenshot updated.

@flack
Copy link
Contributor

flack commented Jun 16, 2019

@hebasto awesome!

@hebasto
Copy link
Member Author

hebasto commented Jun 16, 2019

After the e2c8ba9 commit merged there is no straight way to pass function template InitError(const bilingual_str& fmt, const Args&... args) through the Chain interface.

I ask for advice @ryanofsky, @MarcoFalke, @jonasschnelli, @promag.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

Concept ACK

std::string translated_str;
};

inline bilingual_str _(const char* psz, bool translate)
Copy link
Member

Choose a reason for hiding this comment

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

What is the point of the bool argument, when it is always set to true at the call site? Should be called bool ignored or something like this?

enum class Tr{BI;};
inline bilingueal_str_(const char* psz, Tr ignored);


/** Show bilingual error message **/
template <typename... Args>
bool InitError(const bilingual_str& fmt, const Args&... args)
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer if you removed the plain InitError, since it doesn't seem to be required.

Also, would be nice to add InitError to the linter ./test/lint/lint-format-strings.sh

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd prefer if you removed the plain InitError, since it doesn't seem to be required.

If I understand you correctly then what about #15340 (comment)?
Also see: fea324f

Copy link
Member

Choose a reason for hiding this comment

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

I mean that InitError could take as first argument a string or bilingual string, so that the formatting always happens inside of InitError. Then add InitError to the linter.

@hebasto
Copy link
Member Author

hebasto commented Jun 17, 2019

After the e2c8ba9 commit merged there is no straight way to pass function template InitError(const bilingual_str& fmt, const Args&... args) through the Chain interface.

The solution is #16224.

Should this PR be closed?

@hebasto
Copy link
Member Author

hebasto commented Jun 17, 2019

Closing in favor of #16224 which provides a different approach and works with the Chain interface as expected.

@hebasto hebasto closed this Jun 17, 2019
@hebasto hebasto deleted the 20190204-bilingual-initerror branch July 18, 2019 15:15
maflcko pushed a commit that referenced this pull request May 8, 2020
18bd83b util: Cleanup translation.h (Hennadii Stepanov)
e95e658 doc: Do not translate technical or extremely rare errors (Hennadii Stepanov)
7e923d4 Make InitError bilingual (Hennadii Stepanov)
917ca93 Make ThreadSafe{MessageBox|Question} bilingual (Hennadii Stepanov)
23b9fa2 gui: Add detailed text to BitcoinGUI::message (Hennadii Stepanov)

Pull request description:

  This is an alternative to #15340 (it works with the `Chain` interface; see: #15340 (comment)).
  Refs:
  - #16218 (partial fix)
  - #15894 (comment)

  This PR:
  - makes GUI error messages bilingual: user's native language + untranslated (i.e. English)
  - insures that only untranslated messages are written to the debug log file and to `stderr` (that is not the case on master).

  If a translated string is unavailable only an English string appears to a user.

  Here are some **examples** (updated):

  ![Screenshot from 2020-04-24 17-08-37](https://user-images.githubusercontent.com/32963518/80222043-e2458780-864e-11ea-83fc-197b7121dba5.png)

  ![Screenshot from 2020-04-24 17-12-17](https://user-images.githubusercontent.com/32963518/80222051-e5407800-864e-11ea-92f7-dfef1144becd.png)

  * `qt5ct: using qt5ct plugin` message is my local environment specific; please ignore it.

  ---

  Note for reviewers: `InitWarning()` is out of this PR scope.

ACKs for top commit:
  Sjors:
    re-tACK 18bd83b
  MarcoFalke:
    ACK 18bd83b 🐦

Tree-SHA512: 3cc8ec44f84403e54b57d11714c86b0855ed90eb794b5472e432005073354b9e3f7b4e8e7bf347a4c21be47299dbc7170f2d0c4b80e308205ff09596e55a4f96
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 12, 2020
18bd83b util: Cleanup translation.h (Hennadii Stepanov)
e95e658 doc: Do not translate technical or extremely rare errors (Hennadii Stepanov)
7e923d4 Make InitError bilingual (Hennadii Stepanov)
917ca93 Make ThreadSafe{MessageBox|Question} bilingual (Hennadii Stepanov)
23b9fa2 gui: Add detailed text to BitcoinGUI::message (Hennadii Stepanov)

Pull request description:

  This is an alternative to bitcoin#15340 (it works with the `Chain` interface; see: bitcoin#15340 (comment)).
  Refs:
  - bitcoin#16218 (partial fix)
  - bitcoin#15894 (comment)

  This PR:
  - makes GUI error messages bilingual: user's native language + untranslated (i.e. English)
  - insures that only untranslated messages are written to the debug log file and to `stderr` (that is not the case on master).

  If a translated string is unavailable only an English string appears to a user.

  Here are some **examples** (updated):

  ![Screenshot from 2020-04-24 17-08-37](https://user-images.githubusercontent.com/32963518/80222043-e2458780-864e-11ea-83fc-197b7121dba5.png)

  ![Screenshot from 2020-04-24 17-12-17](https://user-images.githubusercontent.com/32963518/80222051-e5407800-864e-11ea-92f7-dfef1144becd.png)

  * `qt5ct: using qt5ct plugin` message is my local environment specific; please ignore it.

  ---

  Note for reviewers: `InitWarning()` is out of this PR scope.

ACKs for top commit:
  Sjors:
    re-tACK 18bd83b
  MarcoFalke:
    ACK 18bd83b 🐦

Tree-SHA512: 3cc8ec44f84403e54b57d11714c86b0855ed90eb794b5472e432005073354b9e3f7b4e8e7bf347a4c21be47299dbc7170f2d0c4b80e308205ff09596e55a4f96
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants