Here is a patch that add field information to exception message on validation exception when setting a value.
Because it was not easy to know which field raised the exception when saving a lot data in batch.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

DuaelFr’s picture

Here is a new patch, rerolled on the last dev version and covering the two invalid data exceptions.
It is really thin and would improve DX a lot, so please commit it.

This patch is part of the #1day1patch initiative.

wodenx’s picture

Giving this a bump. Would be very helpful for services_entity (and for RESTws, too, I imagine).

wodenx’s picture

joachim’s picture

This would HUGELY improve the DX when working with entity wrappers.

When working in batches, or with queue processing, or even in UIs with a lot of data, it's really hard to get to the root of problems.

Here's an updated patch which goes quite a bit further in what it outputs.

You get a complete chain of the property that you're trying to set. Here are some examples:

  $wrapper = entity_metadata_wrapper('node', 1);
  $wrapper->author->created->set('NOT A TIMESTAMP!');

Error message
EntityMetadataWrapperException: Invalid data value "NOT A TIMESTAMP!" given for wrapper chain node:1->author->created. in EntityMetadataWrapper->set() (line 122 of sites/all/modules/contrib/entity/includes/entity.wrapper.inc).

  $node = entity_create('node', array('type' => 'article'));
  $wrapper = entity_metadata_wrapper('node', $node);
  $wrapper->author->created->set('NOT A TIMESTAMP!');

Error message
EntityMetadataWrapperException: Invalid data value "NOT A TIMESTAMP!" given for wrapper chain node:->author->created. in EntityMetadataWrapper->set() (line 122 of sites/all/modules/contrib/entity/includes/entity.wrapper.inc).

That clearly shows the developer exactly which property was being incorrectly set, with a full chain.

robcolburn’s picture

I don't believe we apply t() function to error messages, do we?

joachim’s picture

Core is inconsistent, so I checked the coding standards: https://drupal.org/node/608166

All Exceptions must include an appropriate translated string as a message, unless the Exception is thrown very early in the bootstrap process before the translation system is available. That is extremely rare.

adam_b’s picture

Applied the patch in #4 and it does give a bit more information for me, but not much...

EntityMetadataWrapperException: Invalid data value given. Be sure it matches the required data type and format. in EntityDrupalWrapper->set() (line 736 of /homepages/31/d292789962/htdocs/pitda_20140118/profiles/commons/modules/contrib/entity/includes/entity.wrapper.inc).

becomes

EntityMetadataWrapperException: Invalid data value "" given for wrapper chain user:. in EntityDrupalWrapper->set() (line 756 of /homepages/31/d292789962/htdocs/pitda_20140118/profiles/commons/modules/contrib/entity/includes/entity.wrapper.inc).

So it's pointing me towards something in the user (which I suspected anyway) - is there any way to get more information than that?
Apologies, but I'm a sitebuilder rather than a developer - so I'm probably missing something obvious here.

joachim’s picture

@adam_b: Could you paste the code that causes the exception please?

adam_b’s picture

Hi Joachim - the error is triggered by the cron run.

But that probably doesn't help much - this is a Drupal Commons installation so has a lot of components. The problem only started late last week, so is probably related to some update or config change - the only one I can think of is an update to Commons 7x-1.5 which I did about that time.

robcolburn’s picture

@joachim,
I'm still learning Drupal's data-structure intricacies myself. Is it possible for value an object or something of greater complexity?

@adam_b,
It will not be pretty, but you might try replacing these lines

   '!value' => is_array($value) ? serialize($value) : $value,

With

   '!value' => "value:" . serialize($value)  . "\n" . "info: . serialize($this->info),

That should spit up quite a bit of php-soup, but should provide more data to sort through.

adam_b’s picture

@robcolbourn: thanks but I'm getting a WSOD:
Parse error: syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in /homepages/31/d292789962/htdocs/pitda_20140118/profiles/commons/modules/contrib/entity/includes/entity.wrapper.inc on line 259

The code I'm using from line 117 of /includes/entity.wrapper.inc is:

  /**
   * Set a new data value.
   */
  public function set($value) {
    if (!$this->validate($value)) {
      throw new EntityMetadataWrapperException(t('Invalid data value "!value"!serialized given for wrapper chain !chain.', array(
        // An exception's message is output through check_plain().
		'!value' => "value:" . serialize($value)  . "\n" . "info: . serialize($this->info),
        '!serialized' => is_array($value) ? ' (serialized)' : '',
        '!chain' => $this->debugIdentifierChain(),
      )));
    }
    $this->clear();
    $this->data = $value;
    $this->updateParent($value);
    return $this;
  }
texas-bronius’s picture

Super work here. I'm also interested in this, but let me open for discussion whether we need so much info:

  • At this point *anything* is better than *nothing.*
    What you've provided in patch looks good but provides a BOATLOAD of info onscreen during dev and in watchdog.
  • "Less is more": What gets us to the source quickest? Maybe an option to provide more data is appropriate?
    Is it reasonable to propose that the 90% use case of this exception handler is devs new to Entity API and that their exception will be limited to a specific snippet of php code they just wrote 2 min prior to trying it out?
  • Assuming these conditions, how do you feel about providing something like:

    Invalid data value given. Be sure it matches the required data type and format.

    becomes

    Invalid data value given. Be sure it matches the required data type and format. Field %field expects type of %type, "!value" received.

    Maybe even a mention of whether it's a required field or not, etc.

One other point to consider: I appended the error-specific message above so that the first part remains unchanged. Who knows what ppl are doing with their watchdog logs and how they're reading it-- wouldn't want to upset someone's process.

* All that said, if we did provide more info, in my case, it sure would be great to just have the Exception::getTrace()[1] (skips EntityMetaWrapperException method and provides just the file and line number with offending call. BAM!

texas-bronius’s picture

I think #1925412: Malformed Entities Throw Exception, better error reporting needed is related and could be marked a dup of this.
Btw, @adam_b your snippet is just missing a closing apostrophe after "'info:" to compile.

spidersilk’s picture

I've been getting this error on all page nodes on a site, following trying to migrate content over from an older D6 site, and after applying this patch, I now get:

"EntityMetadataWrapperException: Invalid data value "P" given for wrapper chain node:. in EntityDrupalWrapper->set() (line 756 of [path to web directory]/profiles/gp_profile/modules/contrib/entity/includes/entity.wrapper.inc)."

...But I still have no idea what on earth that means. Apparently something somewhere is set to a value of "P", but I have no idea WHAT is set to P, WHY it is set to P, or what it's supposed to be set to instead. I did try searching the entire database for fields that were set simply to P, and the only ones I found were in the bueditor_buttons table. I disabled BUeditor in hopes that maybe that was it, but it didn't help - the error's still there. Even though now there is no field set to P anywhere active any more.

Does anyone have any idea what might be causing this?

texas-bronius’s picture

Title: Add field information to exception message on validation exception » Entity Metadata Wrapper: Add field information to exception message on validation exception

@spidersilk - I think it's not saying anything about a value P but an identifier P. Something like $entity_wrapper->field_reference->P->value() or something, where P is some other entity in the chain. Maybe "P" is derived from some string like "Profile" but is incorrectly referencing an assumed array of Profiles but actually just chops the string ("Profile"[0] == 'P').

It probably doesn't help you much, however, and since this thread is about disambiguating this exact error, you might have better luck reposting your inquiry as a support message in the Migrate module (or whatever you're using to migrate data). Or, if you care to tinker a bit and apply @adam_b's snippet in #11 above (plus a trailing quote after "info:" in his snippet to correct the syntax), then you can reply here with a review of whether his patch was helpful to finding the exact source of the issue or not.

Good luck
-Bronius

spidersilk’s picture

Thanks, Bronius - I was actually able to pin it down some while after I posted this, and the culprit was actually Panels! Or more specifically a custom module of pane styles that a previous developer had made using Panels. Not sure yet exactly why or how it caused the error, but when I disabled it, everything was OK. So in my case it was not Entity's fault after all. :)

bgrobertson’s picture

The patch in #4 saved my life. This definitely should be added! Thank you!

HansKuiters’s picture

Status: Needs review » Reviewed & tested by the community

Patch in #4 works fine. Thanks.

kenorb’s picture

Tested and works fine.

Arne Slabbinck’s picture

Thanks! Patch #4 helps out allot while debugging

fago’s picture

Indeed, that's a great improvement. I'd suggest using var_export() instead of serialization though -> I adapted the patch a bit. Interdiff attached.

fago’s picture

fago’s picture

Status: Reviewed & tested by the community » Fixed
FileSize
3.49 KB

And committed - thanks. Please make sure to test the dev version also, but in my tests it was fine!

  • fago committed 8906117 on 7.x-1.x authored by joachim
    Issue #1621226 by joachim, DuaelFr, cthiebault, fago: Entity Metadata...

Status: Fixed » Closed (fixed)

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