Jak debugować wyjątek EntityMalformedException?

16

Mam błąd krytyczny EntityMalformedException: Brak właściwości pakietu w jednostce typu node. w instance_extract_ids () (wiersz 7700 z. \ zawiera \ common.inc) podczas próby uzyskania dostępu do użytkownika / xyz .

Próbowałem pobrać informacje o zniekształconym węźle w linii 7700, gdzie budowany jest komunikat o błędzie, myślę:

if (!isset($entity->{$info['entity keys']['bundle']}) || $entity->{$info['entity keys']['bundle']} === '') {
 dpm($info);// or dpm($entity);
 throw new EntityMalformedException(t('Missing bundle property on entity of type @entity_type.', array('@entity_type' => $entity_type)));
}

dpm($entity) zwraca nieoczekiwany obiekt użytkownika, a $ info ogromną ilość rzeczy.

Czy ktoś mógłby postawić mnie na właściwej drodze?

Przeczytałem już wszystko, co mogłem znaleźć na temat błędów właściwości brakujących pakietów , ale żadne nie pomogło w rozwiązaniu.

dpm($entity) zwroty

uid (String, 2 characters ) 70
name (String, 9 characters ) John
pass (String, 55 characters ) $S$DUwPuOuDPiDL4nRTYXqc7a5uOfMKey7pyhOFUEKka1XM...
mail (String, 30 characters ) john@example.com
theme (String, 0 characters )
signature (String, 0 characters )
signature_format (String, 13 characters ) filtered_html
created (String, 10 characters ) 1396286331
access (String, 10 characters ) 1397146661
login (String, 10 characters ) 1396513460
status (String, 1 characters ) 1
timezone (NULL)
language (String, 2 characters ) fr
picture (NULL)
init (String, 30 characters ) john@example.com
data (Array, 5 elements)
roles (Array, 1 element)
og_user_node (Array, 0 elements)
message_subscribe_email (Array, 1 element)
field_bio (Array, 0 elements)
field_name_first (Array, 1 element)
field_name_last (Array, 1 element)
field_facebook_url (Array, 0 elements)
field_linkedin_url (Array, 0 elements)
field_twitter_url (Array, 0 elements)
user_trusted_contacts (Array, 1 element)
group_group (Array, 1 element)
group_access (Array, 1 element)
metatags (Array, 0 elements)
rdf_mapping (Array, 3 elements)
realname (String, 13 characters ) John Doe
content (Array, 13 elements)
entity_view_prepared (Boolean) TRUE
privatemsg_disabled (Boolean) FALSE
Kojo
źródło
Zazwyczaj jest to dość niski poziom, który można dowiedzieć się po prostu przez dpm () 'encji $. Upewnij się, że przekazujesz samą encję - a nie zestaw encji, które zwracają funkcje ładowania encji.
AyeshK
1
Miałem na myśli to, że w zasadzie sprawdza, czy informacje o pakiecie istnieją przed zgłoszeniem wyjątku. Jeśli możesz opublikować dane wyjściowe dpm ($ byt) (oczywiście z poufnymi informacjami niewyraźnymi), to pomoże innym zobaczyć, co jest nie tak.
AyeshK
3
@Kojo Przyczyna jest naprawdę bardzo prosta ... coś woła entity_extract_ids('node', $var);, ale zamiast obiektu węzła $varprzekazuje obiekt użytkownika. Jeśli masz jakieś niestandardowe lub deweloperskie moduły contrib, spróbuj je wyłączać jeden po drugim, aby zobaczyć, że możesz znaleźć winowajcę
Clive
2
Yikes. dpm(debug_print_backtrace());będą tu bezcenne. Możesz zobaczyć, który moduł zaczął to wszystko, podążając za funkcjami z powrotem do początku żądania
Clive
1
Nie martw się, jeśli zainstalujesz i skonfigurujesz xdebug xdebug.collect_params = 4, znacznie ułatwi ci to życie
Clive

Odpowiedzi:

30

Błąd:

EntityMalformedException: brak właściwości pakietu w encji typu node.

tak się dzieje, ponieważ twoja właściwość pakietu jest zniekształcona podczas ładowania lub zapisywania, więc Drupal nie może znaleźć, jaki to rodzaj pakietu.

Logika tego wyjątku jest następująca:

// Explicitly fail for malformed entities missing the bundle property.
if (!isset($entity->{$info['entity keys']['bundle']}) || $entity->{$info['entity keys']['bundle']} === '') {
  // var_dump(debug_backtrace()); exit; // You may want this line to debug.
  throw new EntityMalformedException(t('Missing bundle property on entity of type @entity_type.', array('@entity_type' => $entity_type)));
}

Więc w zasadzie wartości $info['entity keys']['bundle'](dla węzła to:) typenie można znaleźć w $entityobiekcie ( $node->typedla węzła), dlatego Drupal nie wie, z jakim bytem ma do czynienia. Więc najprawdopodobniej twój byt jest nieprawidłowy (np. Ładujesz coś innego) lub jest po prostu pusty ( $entityjest NULL).


Jeśli nie zmodyfikowałeś żadnego kodu Drupal, może to być spowodowane różnymi czynnikami (najprawdopodobniej konkretnym błędem modułu Drupal), takimi jak:

Oto odpowiedzialny kod generowany przez rdzeń Drupala (plik:) common.inc:

 if (!empty($info['entity keys']['bundle'])) {
    // Explicitly fail for malformed entities missing the bundle property.
    if (!isset($entity->{$info['entity keys']['bundle']}) || $entity->{$info['entity keys']['bundle']} === '') {
      throw new EntityMalformedException(t('Missing bundle property on entity of type @entity_type.', array('@entity_type' => $entity_type)));
    }
    $bundle = $entity->{$info['entity keys']['bundle']};
  }

Debugowanie

Jeśli nie rozpoznajesz niczego powyżej, najłatwiejszą metodą debugowania tego rodzaju błędu jest umieszczenie var_dump(debug_backtrace());lub dd(debug_backtrace());(gdy Devel jest włączony) przed rzeczywistym throw new EntityMalformedExceptionw linii, której dotyczy problem common.inc.

Uwaga: użycie dd()funkcji z Devel wygeneruje informacje debugowania do pliku w folderze tymczasowym Drupal ( temporary://drupal_debug.txt) z zrzutem śladu wstecznego, w przeciwnym razie może być zbyt duży i trudny do odczytania podczas zrzutu na ekran. Podczas korzystania var_dump()łatwiej jest zadzwonić die();po połączeniu i sprawdzić zrzut w trybie widoku źródła strony.

Jeśli dzieje się tak podczas zapisywania węzła, sprawdź ten wpis EntityMalformedException w SO, aby uzyskać bardziej szczegółowe instrukcje.


Zobacz także następujący problem Drupal: # 1778572, aby uzyskać więcej pomysłów.

kenorb
źródło
2
chwała za tak szczegółową odpowiedź! Rozwiązałem ten problem dawno temu, ale nie mam wątpliwości, że będzie to pomocne dla wielu osób, w tym mnie.
Kojo,
3
To fantastyczna odpowiedź! Zasługuje na więcej pochwał.
Christian
Dodałem dd(debug_backtrace());do dotkniętej linii przed throw new EntityMalformedException, upewniłem się, że Devel jest włączony i uruchomiłem komendę drush w cronie, która generuje ten błąd i nie otrzymuję żadnych danych debugowania. Co zrobiłem źle? Dzięki!
Christia
1
Znaleziono: polecenie utworzyło plik o nazwie drupal_debug.txtinside, /tmp/drupal_theme/gdzie „drupal_theme” to nazwa motywu drupal. Dziękujemy za doskonałą pomoc w debugowaniu!
Christia
8

Dzięki komentarzom Clive rozwiązałem problem w następujący sposób.

Dodano ddebug_backtrace()miejsce wystąpienia błędu ( entity_extract_ids (), wiersz 7700 z. \ Zawiera \ common.inc ), aby wydrukować stos wywołań funkcji.

Następnie szukając czegoś nieoczekiwanego w danych wyjściowych, odkryłem, że problemem może być reguła widoczności okienka .

19: ctools_entity_field_value_ctools_access_check() (Array, 2 elements)
  file (String, 81 characters ) profiles\commons\modules\contrib\ctools\plugins...
  $...['19: ctools_entity_field_value_ctools_access_check()']['file']
    profiles\commons\modules\contrib\ctools\plugins\access\entity_field_value.inc:213
  args (Array, 3 elements)
    0 (Array, 2 elements)
      field_theme (Array, 1 element)
      //...

Miałem zastosowano poprawkę na entity_field_value.inckilka dni temu po prostu rozwiązać zawiadomienie reguły widoczność ... i stworzył zasadę widoczności test z warunku field_theme.

Teraz cofanie poprawki lub usuwanie reguły widoczności okien rozwiązało bieżący błąd EntityMalformedException ... Potężny ddebug_backtrace()!

Kojo
źródło
Wypróbowałem tę metodę i uzyskałem 1000 linii kodu na interfejsie. Jak widzisz, gdzie jest błąd?
Sam
@Sam spojrzał na odpowiedź Kenorba, może ci pomóc
Kojo
0

Ten problem pojawia się, gdy istnieją osierocone węzły, po prostu się ich pozbądź, a cron będzie działał bez żadnego błędu. Indeksowanie wyszukiwania w końcu osiągnie 100%. Przed kontynuowaniem wykonaj kopię zapasową bazy danych.

Zakładając, że masz dostęp do phpMyAdmin, uruchom ten kod SQL, aby zidentyfikować węzły, a następnie je usunąć. Zastąp moje pytanie nazwa typu zawartości maszyny nazwą twojego konkretnego typu zawartości, jeden po drugim, aż nie uzyskasz żadnego wyniku, to znaczy po usunięciu.

SELECT n.nid, n.title, n.vid, nr.vid FROM drcm_node n LEFT JOIN drcm_node_revision nr ON nr.nid = n.nid WHERE n.type = 'question' AND nr.vid IS NULL ORDER BY n.nid ASC

Możesz usunąć osierocone węzły za pomocą kodu SQL poniżej. Zamień liczby w nawiasie na określone identyfikatory węzłów

DELETE from node where nid IN (12779,12780,12781,12782)

Koech
źródło