Follow up for #1987602: Convert ajax_form_callback() to a new style controller
Problem/Motivation
As specified in #1987602-79: Convert ajax_form_callback() to a new style controller Exception messages shouldn't be translated.
Reasons to not translate exceptions messages (from comments on this issue and #817160: Don't translate exceptions):
- "Additional uncaught exception while handling exception." Calling a whole huge codepath in our exception is liable to obscure the real problem in many situations.
- Adds a dependency on common.inc everywhere we want to throw (or test) an exception. Ugggghh.
- Exception messages are developer-facing strings, and as such, there is no real reason to translate them. As in SimpleTest, we don't need to pollute l.d.o with hundreds upon hundreds of strings no one will care about.
- Googling for translated error messages is more difficult.
- technical issues with ... calling t() ... [especially in the] bootstrap phase ... [and with] ... unit tests.
Proposed resolution
Remove translation of exceptions in code base.
However, it was pointed out that there are user facing exceptions, at least field errors are such., so we may have to specify when it is OK to translate exception messages or refactor these to error messages.
Coder sniff DrupalPractice.General.ExceptionT
added to 8.9 in #3134731: Update coder to 8.3.9
Remaining tasks
- Update Coding standards - PHP Exceptions.
- Create a patch (or several patches) that removes all translations of exception messages.
User interface changes
Not really, exceptions should not be shown to end users
API changes
No.
Original report by @xjm
#1987602-79: Convert ajax_form_callback() to a new style controller
Comment | File | Size | Author |
---|---|---|---|
#71 | interdiff-2055851-55-71.txt | 7.71 KB | sja112 |
#71 | 2055851-71.patch | 41.62 KB | sja112 |
#56 | 2055851-55.patch | 34.9 KB | andypost |
#56 | interdiff.txt | 825 bytes | andypost |
#53 | 2055851-53-do-not-commit.patch | 2.24 KB | andypost |
Comments
Comment #1
effulgentsia CreditAttribution: effulgentsia commentedIs there an issue somewhere that explains why not, and whether it covers all exception messages or only some? For example, in authorize_filetransfer_form_validate(), we have
throw new Exception(t('The connection protocol %backend does not exist.', array('%backend' => $backend)));
, which on first glance, seems like a reasonable thing to translate, unless there's a reason for not translating any exception message. On the other hand, #1987602-79: Convert ajax_form_callback() to a new style controller points outthrow new HttpException(500, t('Internal Server Error'));
, and given that "Internal Server Error" is a standard reason phrase defined in http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1, I could see us not wanting to translate that, though even that document says, "The Status-Code is intended for use by automata and the Reason-Phrase is intended for the human user. The client is not required to examine or display the Reason- Phrase.", which makes me think translation of even an HTTP reason phrase could be useful.Comment #2
vijaycs85Thanks for starting this conversation @effulgentsia. Just found that we already have documentation for exceptions here PHP Exceptions saying that we have to translate messages except the one that can be thrown before bootstrap. However @xjm or @alexpott can provide more insight on what need to be done here.
Comment #3
xjmSo, https://drupal.org/node/608166 totally contradicts what I learned, and I think it's wrong for several reasons:
common.inc
everywhere we want to throw (or test) an exception. Ugggghh.Now, if we catch the exception message and then pass it to other error handling, we could translate it then, I suppose. But putting
t()
inside an exception seems quite unwise.Comment #4
effulgentsia CreditAttribution: effulgentsia commentedOnly relation to WSCII conversions is that some controllers throw exceptions, but so does lots of other code, so untagging.
Comment #5
claudiu.cristeaIs there a final/official point of view here? Should we translate or not exception messages?
@xjm, if NO, can you update https://drupal.org/node/608166 to reflect this new policy?
Comment #6
fietserwin+1 for no longer translating exception messages. All the reasons from #3, plus that developers,e ven if they don't (exactly) understand the message can still search for it and use google translate to translate the pages found that hopefully describe a solution.
How many times I have tried to search for a translated message and not finding any useful...
Comment #7
fietserwinClosed #817160: Don't translate exceptions as duplicate and updated the issue summary to incorporate comments from this and the other issue.
Comment #8
tim.plunkettI couldn't help someone in IRC today because their exception message was translated.
+1
Comment #9
dawehnerStarted to convert all beside the one in the installer, and some of the http ones.
Comment #11
dawehnerUps.
Comment #12
fietserwinAfter applying your patch I found these remaining ones.
Besides the installer and updater ones, which indeed seem to be user facing (system administrator, bu that may be a starter who wants to play with Drupal ), there are:
- drupal\core\lib\Drupal\Core\Database\Driver\fake\FakeMerge.php, 40
- drupal\core\modules\rdf\rdf.module, 118
However, I also found this piece of code in drupal\core\lib\Drupal\Core\Database\Install\Tasks.php, 150-:
Thus 10 lines above we have one of the exceptions to the rule, but directly below we have a not-translated user facing string. This should be made consistent. Personally, I prefer to translate the $message on line 157, and consequently the task messages online 34-71 as well. BTW: the message should be formatted and the link should be extracted as a parameter.
I din't search for other - more obscured, more difficult to find than these - translated exceptions, but I might do a brute search and quick scan later on.
Comment #13
fietserwinI found 2 more translated exceptions (using regexp /throw new .*Exception\([^'"S)]/ (all throw's except with a plain message (', "), a String::format message,or no message [)] (and ignoring everything under vendor):
- drupal\core\modules\image\src\Controller\ImageStyleDownloadController.php, 133:
- drupal\core\lib\Drupal\Core\Extension\InfoParser.php, 44:
Comment #14
Lars Toomre CreditAttribution: Lars Toomre as a volunteer commentedThis issue needs a re-roll since String::format has been eliminated in preparation for PHP7.
Comment #15
Mac_Weber CreditAttribution: Mac_Weber as a volunteer commentedRerolled and took care of the
String::format
as pointed by @Lars Toomre at #14Comment #17
Mac_Weber CreditAttribution: Mac_Weber as a volunteer commentedNow it will pass tests. It was missing a class aliasing in one file.
Comment #18
dawehnerMhh, do we really want to remove the possibility in the installer to translate those error messages?
Comment #19
Gábor HojtsyI agree, the installer can translate a lot of things. Some of the reasons listed in the summary are totally valid though. Are these messages actually internal and developer-facing or are we using exceptions to let frontend users know about things?
Comment #20
Mac_Weber CreditAttribution: Mac_Weber as a volunteer commented@Gábor Hojtsy @dawehner whenever it is
throw new InstallerException()
then it means it is non-interactive install. For interactive install the exception title and message must be rendered.As the non-interactive install is usually done by more advanced users, then I think it is ok to not translate. The only reason I see for translating them is in case of a custom installer which runs the command line under the hood and catches these exception messages. Do we need to worry about it?
Comment #21
Gábor HojtsyThat sounds contradicting. If its only thrown in non-interactive, how can an interactive install display its title and message?
Comment #22
Mac_Weber CreditAttribution: Mac_Weber as a volunteer commented@Gábor Hojtsy for non interactive it is not thrown directly. It has to be rendered, such as in the file
install.core.inc
:The conditional for non-interactive throws directly, while for interactive install it prepares a renderable array.
Comment #23
Gábor HojtsyRight, so should it be rethrown then with a FormattableMarkup wrapper (getting the string and replacements out of t()) then? So it works for both cases? Or does that not help the cause of the issue?
Comment #24
Mac_Weber CreditAttribution: Mac_Weber as a volunteer commented@Gábor Hojtsy I am not sure if the exception massage for that piece of code (#22) is a static string. Probably not.
I think we should not care about it in this issue.
Comment #30
andypostLooks it needs change record or documentation updates to explain how to use formatting in exceptions
https://www.drupal.org/docs/develop/coding-standards/php-exceptions
https://www.drupal.org/docs/8/api/database-api/error-handling
Comment #31
dawehnerComment #32
borisson_Instead of a reroll I made this patch again from scratch, I didn't use
FormattableMarkup
though, I used string interpolation instead. I used the regex from #13 to find all Exceptions to replace.Comment #36
Chi CreditAttribution: Chi commentedWe probably need to grep it once again as core may have got more translated exceptions since the last patch was submitted.
Comment #37
jungleRerolled from #32
Comment #38
init90Thanks for work here. Here some minor points:
According to the documentation in section about exceptions, we should wrap variables into single quotes:
https://www.drupal.org/docs/develop/coding-standards/php-exceptions
We should apply that rule to all instances. I think it really can make the exception messages a bit easier to read.
Here we can get a bit better result with sprintf:
sprintf will be better here:
The same here
and here
also here
I think that sprintf will be a bit better here
+1 to sprintf
+1 to sprintf
+1 to sprintf
+1 to sprintf
+1 to sprintf
Comment #39
jungle@init90 thank you for your detailed review.
There is a filed issue to replace sprintf usages by dot concatenation or variable inside string, so i do not think it is necessary to use sprint here.
Comment #40
jungleAddressed #38.1
Comment #41
init90@jungle, thanks for your feedback. I don't think that performance matters for exception messages.
But in general, I realize that my points about sprintf are contradictory, so I think we can implement only point 1 from #38 and leave decision about sprintf on commiters.
UPD: opps..when I was writing the message, the first point already had been implemented
Comment #42
jungle@init90 IMO
Comment #44
jungleFix Drupal\Tests\dblog\Functional\DbLogResourceTest
Comment #45
andypostLooks this issue should be postponed on #3123061: Create a sniff to make sure exception messages are not translated
Also policy about
sprintf()
is not accepted yet #3118957: Evaluate replacing all usage of sprintf by dot concatenation or variable inside stringComment #47
init90I think it ready for the final review. Thanks!
#42 make sense, but my opinion from #41 that in general it's not critical, still with me:)
#45 IMO better to keep the issues in parallel, at least it allows having proper examples in the core and gets results quicker.
Comment #48
andypostAs a bug it needs test - in this case a sniffer, otherwise it will happen again and the policy for interpolation is a second blocker
Comment #50
init90One blocker is in - code sniff was added recently.
@andypost what do you mean under "policy for interpolation"?
Comment #51
jungleI think. the blocker was in, coder 8.3.9 was committed
Comment #52
andypostBur policy still needs to resolve #3118957: Evaluate replacing all usage of sprintf by dot concatenation or variable inside string
Comment #53
andypostQuick run of new sniff and quick re-roll for 9.1 + sniffer changes from https://git.drupalcode.org/project/coder/commit/a7c6a38
Comment #54
andypostout of scope change
Comment #55
andypostMissed to add patch for #54
Comment #56
andypostFix for leftover from patch #53
Comment #57
xjmWow, blast from the past! Glad to see this issue getting addressed.
Comment #58
quietone CreditAttribution: quietone as a volunteer commentedScanned the patch visually and noticed this.
Doesn't seem to be in scope, there is no t() function.
Comment #59
sja112 CreditAttribution: sja112 at Srijan | A Material+ Company for Srijan | A Material+ Company commented@quietone, I have updated the patch.
The change is not required here.
Comment #61
sja112 CreditAttribution: sja112 at Srijan | A Material+ Company for Srijan | A Material+ Company commented@quintone,
Why
$this->assertResourceErrorResponse(404, "Log entry with ID '9999' was not found", $response);
is used instead of$this->assertResourceErrorResponse(404, 'Log entry with ID 9999 was not found', $response);
?Because we have this,
change in the patch we have to add id
'9999'
in quotes instead of something like this9999
.Moving ticket back for review. Patch #56 works.
Comment #62
quietone CreditAttribution: quietone as a volunteer commented@sja112, thanks for the explanation.
Yes, the patch in #56 is correct. I would RTBC but I don't know about changes to phpcs.xml.dist.
Comment #63
andypostCoder sniff
DrupalPractice.General.ExceptionT
added to 8.9 in #3134731: Update coder to 8.3.9PS: added to summary
Comment #64
longwave#56 looks ready to go.
Comment #65
andypostLooks coder needs another bump for false positives #3123061: Create a sniff to make sure exception messages are not translated
It could be done in follow-up
Comment #66
xjmHEAD has a mix of
sprintf()
and just$variable
inside double quotes or with dot concatenation, so I think the simplest pattern here is best for now. (Also not convinced that we should worry that much about micro-optimizing performance when exceptions are thrown; they should not be happening under normal site operation generally.)Adding reviewer credits.
Comment #69
xjmReviewed locally with
git diff --color-words
and verified that the only changes are:t()
,t()
,Then to verify that all of core passed with the rule enabled, I ran:
[ibnsina:maintainer | Mon 19:21:27] $ composer run phpcs -- -sp
Committed to 9.1.x. Then, since it's a beta-eligible coding standards change, cherry-picked to 9.0.x and 8.9.x (re-running the core ruleset in both cases). 9.0.x passed, so I pushed that commit; however, looks like 8.9.x has some additional instances that need to be fixed:
Setting PTBP for a current 8.9.x version of the patch. Thanks!
Comment #70
sja112 CreditAttribution: sja112 at Srijan | A Material+ Company for Srijan | A Material+ Company, Drupal India Association commented@xjm,
Adding patch with the fixes for the 8.9.x branch.
Comment #71
sja112 CreditAttribution: sja112 at Srijan | A Material+ Company for Srijan | A Material+ Company, Drupal India Association commentedFixed test case failure error.
Comment #72
xjmThanks @sja112! Setting "Needs review" for the backport.
Comment #73
xjmComment #74
jungle#66, @xjm, got it, thanks for your comment!
#69 addressed, LGTM, thanks @sja112!
Comment #75
jungle>Replacing placeholders with variables, and delimiting them with single quotes for readability,
I doubt that there are many exception messages which do not follow this (haven't checked it). Is it worthy to file a new issue, or ignore it just like ignoring the micro-optimization of
sprintf()
and dot concatenation?Comment #76
xjm@jungle We could file a coding standards issue for what the "preferred" format is if we want, but I don't think it matters all that much, so long as we're not complicating the call stack and obscuring debugging info. :)
Comment #78
xjmReviewed the interdiff for #71. Random observations:
Markup in exception messages is interesting; I think this gets sanitized as plain text? Anywho, out of scope.
Also, the database drivers really liked their translated exception messages. I guess this is because they were some of the first things in core to use proper exceptions, and so were written before we had a good grasp on what the consequences would be.
I checked the patch locally with
git diff --color-words
to validate that it was changing all the correct things as in #69. Finally, I rancomposer run phpcs -- -sp
locally again to verify that the rule is now passing everywhere for 8.9.x.Committed and pushed to 8.9.x. Thanks!
Comment #79
jungle#76, To whom may want to file a new issue. Maybe. quoting with
``
is better than using single quotes.@xjm, thank you for committing!
Comment #80
xjmComment #82
cburschkaThis change had a small syntax error; see #3150990: Updater::install() crashes on file transfer exceptions..
Comment #83
jonathan1055 CreditAttribution: jonathan1055 as a volunteer commentedAdding parent as this commit added a DrupalPractice sniff to phpcs.xml.dist