\Drupal\tmgmt_content\Plugin\tmgmt\Source\ContentEntitySource::doSaveTranslations() throws an exception when there is data for a field tha doesn't exist (anymore).

There are valid reasons how that could happen, for example because a field was deleted, or it could have been renamed, like the block_content.content_translation_status field during the 8.5.0 update.

Issue fork tmgmt-2955555

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Berdir created an issue. See original summary.

thoreauinsf’s picture

Priority: Normal » Critical
thoreauinsf’s picture

is there a work around or a way to patch for this? I have an entire site blocked from accepting translations because a field was removed from the content type -and Drupal is throwing an exception on accepting content.

thoreauinsf’s picture

is anyone working on this module monitoring this bug? its been up here for a month with no answer.

berdir’s picture

The workaround is commenting out the exception. Patches to do that it are welcome. Nobody is paid to maintain this module, most of our time spent maintaining it is our free time. Unless someone is funding the work or it affects our own clients, we don't guarantee any response times.

thoreauinsf’s picture

Totally okay. I appreciate the response.

replicaobscura’s picture

Here's a patch that displays a warning message and skips processing that field instead of exiting with an exception.

replicaobscura’s picture

Status: Active » Needs review
berdir’s picture

Status: Needs review » Needs work

Thanks. The problem is that a drupal_set_message() will end up nowhere when for example automatically accepting jobs and they are coming through a notification callback or a cron job. Instead, it would be better to add this as a message the job which means we need to make that available in that method somehow.

maebug’s picture

Status: Needs work » Needs review
StatusFileSize
new2.94 KB

I modified the warning to include the job item ID and a link to the job item page. The warning now gets added as a job message, displayed to the user, and logged. Let me know if this is a bit overkill, but I think it's a good idea to at least display the message to the user upon saving so there's no confusion about missing fields. In the case of cron jobs or automatically accepting jobs, the warning will be stored in the logs and as a job message.

maebug’s picture

Whoops, I forgot to remove @throws from the function's docblock.

berdir’s picture

Status: Needs review » Needs work
+++ b/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php
@@ -359,7 +358,19 @@ class ContentEntitySource extends SourcePluginBase implements SourcePreviewInter
+        \Drupal::logger('tmgmt_content')->warning($message, $args);
+        \Drupal::messenger()->addWarning($this->t($message, $args));
+

our UI's automatically display messages that were added while accepting, this should really not be necessary.

Having a test that does this would allow us to prove that fairly easy. Copy an existing one, delete a field before accepting.

akbuje’s picture

I have made the changes suggested in #12 by Berdir.

However, I am not used to writing tests, but if someone could give me a few pointers, I would be happy to give it a try.

We are using this patch in production, to avoid some issues related to this exception.

akbuje’s picture

Status: Needs work » Needs review
berdir’s picture

Have a look at \Drupal\Tests\tmgmt_content\Functional\ContentTmgmtEntitySourceUiTest::testNodeTranslateTabSingleCheckout for example, the part until "$this->drupalPostForm(NULL, array(), t('Save as completed'));" creates a node with various fields, then creates a job, submits it and then accepts it.

Copy that into a new test method like testNodeTranslateMissingField(), then before you accept, delete e.g. the body field.

berdir’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
larskleiner’s picture

I re-rolled the patch from #13 as it didn't apply to the latest 1.x-dev

stijnstroobants’s picture

The patch in #17 applies but does not correctly work.
It throws the following error: Error: Call to undefined method Drupal\tmgmt\Entity\JobItem::url() in Drupal\tmgmt_content\Plugin\tmgmt\Source\ContentEntitySource->doSaveTranslations() (line 503 of modules/contrib/tmgmt/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php).

stijnstroobants’s picture

stijnstroobants’s picture

Status: Needs work » Needs review
stijnstroobants’s picture

Something wrong with the patch. Created a new one.

stijnstroobants’s picture

oheller’s picture

The url object was being passed to the @link placeholder which when processed gives the following warning for each field:
Warning: htmlspecialchars() expects parameter 1 to be string, object given in Drupal\Component\Utility\Html::escape() (line 424 of core/lib/Drupal/Component/Utility/Html.php) and the trace.

I've switched the token to '@link' => $item->toUrl()->toString(), to get the string. This eliminates the warnings.

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php
    @@ -482,8 +482,6 @@ class ContentEntitySource extends SourcePluginBase implements SourcePreviewInter
        *   (optional) Whether to save the translation or not.
        *
    -   * @throws \Exception
    -   *   Thrown when a field or field offset is missing.
    

    the removed documentation also mentions an exception is thrown when a delta does not exist. that could in theory still happen if we attempt to set a non-sequential delta, so maybe we should be a little bit more careful about that or for now keep the @throws.

  2. +++ b/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php
    @@ -501,7 +499,17 @@ class ContentEntitySource extends SourcePluginBase implements SourcePreviewInter
     
           if (!$translation->hasField($field_name)) {
    -        throw new \Exception("Field '$field_name' does not exist on entity " . $translation->getEntityTypeId() . '/' . $translation->id());
    +        $message = 'Skipping field %field for job item <a href="@link">@item</a> because it does not exist on entity <em>@type/@id</em>.';
    +        $args = [
    +          '%field' => $field_name,
    +          '@link' => $item->toUrl()->toString(),
    

    I don't think it makes sense to link to the job item, this is already logged on the job item and has a link through that.

    Instead, as a user-facing message, we should use a linked label, with $translation->toLink()->toString(). But check with $translation->hasLinkTemplate('canonical') and don't link it if not, just use $translation->label() then.

er.garg.karan’s picture

Is this issue still being worked on? I am facing this issue too often.

vikramsaini1609’s picture

Version: 8.x-1.x-dev » 8.x-1.15
Status: Needs work » Needs review
StatusFileSize
new2.87 KB

I have provided a setting in admin to enable and disabled to throw this error.

er.garg.karan’s picture

Thanks @vikramsaini1609 for this patch.

It worked well for me.

berdir’s picture

Version: 8.x-1.15 » 8.x-1.x-dev
Status: Needs review » Needs work

I don't get the setting. It's not an exception anymore, just a warning, and I think it's worth to always do that, don't see the benefit of hiding the fact that some provided translations couldn't be saved.

The second part of my review in #22 wasn't applied and tests weren't added either as I asked in back in #15.

ioana apetri made their first commit to this issue’s fork.

ioana apetri’s picture

Status: Needs work » Needs review
StatusFileSize
new4.95 KB

Hello, I have provided the changes discussed in #24. Thanks

  • berdir committed cd12beb4 on 8.x-1.x authored by ioana apetri
    Issue #2955555 by ioana apetri, stijnstroobants, maebug, bmcclure,...
berdir’s picture

Status: Needs review » Fixed
Issue tags: -Needs tests

Amazing, a test :)

Thanks, merged.

Status: Fixed » Closed (fixed)

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

ashraf.hussain’s picture

Working fine