Exceptions are not supposed to be translated.
https://www.drupal.org/node/608166#conventions

Comments

Chi created an issue. See original summary.

arkener’s picture

Status: Active » Needs review
klausi’s picture

This is tricky because there could be use cases where it makes sense to use t() in exceptions. For example HttpException where we give a user facing reason. Ideally that message should be translated. Maybe Drupal core already does that when printing the exception and translation is done twice?

Example in Drupal core: ImageStyleDownloadController with the user facing exception message "Image generation in progress. Try again shortly."

On the other hand I don't see where Drupal core's default HTML exception subscriber would even make use of the exception message. I only see JSON API and Serialization module use the exception message and printing that in a HTTP response. Those are API modules, so probably does not count as user facing text?

I ran this sniff on Drupal 8.8 core with ./vendor/bin/phpcs -p --standard=coder_sniffer/DrupalPractice --sniffs=DrupalPractice.General.ExceptionT /home/klausi/workspace/drupal-8/core/modules and checked usages. It seems most warnings are correct where t() really should not be used. I was also checking for false positives because the sniff implementation is very broad, but so far it turned up only correct warnings.

https://www.drupal.org/docs/develop/coding-standards/php-exceptions says "Only messages from the install and update system are currently translated as they are user facing.", so it is good that this sniff is in the DrupalPractice standard which is allowed to have minor false positives.

Given that I think we can go ahead with this.

  • Arkener authored a7c6a38 on 8.x-3.x
    feat(ExceptionT): Add sniff to ensure that exceptions are not translated...
klausi’s picture

Status: Needs review » Fixed

Thanks, committed!

pfrenssen’s picture

This is too broadly implemented, it throws false positives if a translation method is called anywhere inside the exception invocation.

We want this to happen on cases like this:

throw new \Exception($this->t("Something"));

But since exceptions are classes it is possible that they have entirely legitimate custom methods that are intended to be translated. For example in our project we have exceptions that are intended to stop a build pipeline if a certain condition is not met, and our exception class has a custom method setUserMessage() that passes a render array to show to the end user. This message is intended to be translated. This throws a false positive:

      throw (new PipelineStepExecutionLogicException('Graph data could not be inserted', 0, $e))
        ->setUserMessage([
            '#markup' => $this->t('Could not store triples in triple store. Reason: @message', [
              '@message' => $e->getMessage(),
            ]),
          ]);
arkener’s picture

Status: Fixed » Needs review

Good catch, we should only check for translation within the exception itself. Any methods which might be defined on the exception should be excluded from the rule. I've created a PR to properly scope the rule to only check for translations within the exception: https://github.com/pfrenssen/coder/pull/106

pfrenssen’s picture

Status: Needs review » Reviewed & tested by the community

Great job! I checked in my project and no more false positives are reported. Thanks for the quick fix!

andypost’s picture

It means related core issue should wait for next release with the fix

  • Arkener authored d187981 on 8.x-3.x
    fix(ExceptionT): Only check for translation within the exception (#...
klausi’s picture

Status: Reviewed & tested by the community » Fixed

Thanks a lot, merged!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.