2017-09-16 61 views
10

我有以下錯誤:Laravel通知事件監聽器未定義的屬性

Undefined property: Illuminate\Notifications\Events\NotificationSent::$user in /var/www/app/app/Listeners/NoticationListener.php:31

這裏出現的錯誤:

<?php 

namespace App\Listeners; 

use Illuminate\Notifications\Events\NotificationSent; 
use Illuminate\Queue\InteractsWithQueue; 
use Illuminate\Contracts\Queue\ShouldQueue; 

class NoticationListener implements ShouldQueue 
{ 
    /** 
    * Create the event listener. 
    * 
    * @return void 
    */ 
    public function __construct() 
    { 
     // 
    } 

    /** 
    * Handle the event. 
    * 
    * @param NotificationSent $event 
    * @return void 
    */ 
    public function handle(NotificationSent $event) 
    { 
     $notification = $event->notifiable; 
     $addressee = $notification; //error here 
     $address = $notification; 
     $type = "Notification"; 
     dispatch(new SendEmail($type,$addressee,$address)); 
    } 
} 

我不明白這個未定義的屬性,特別是在這條線。我如何從這裏dd()?我試圖登錄$event,但我無法得到它的日誌,只有這個錯誤。

我的通知在應用程序中工作得很好,我只想給他們一個電子郵件,這就是爲什麼我有這個事件監聽器/工作。

謝謝。

EDIT

被分派到該通知的庫代碼是下面:

public function notify($asset) 
{ 
    $users = User::where("id","!=",Auth::user()->id)->get(); 
    Notification::send($users, new NewAsset($asset)); 
} 

Notification類的該擴展低於:

class NewAsset extends Notification 
{ 
    use Queueable; 

    /** 
    * Create a new notification instance. 
    * 
    * @return void 
    */ 
    protected $asset; 

    public function __construct($asset) 
    { 
     $this->asset = $asset; 
    } 

    /** 
    * Get the notification's delivery channels. 
    * 
    * @param mixed $notifiable 
    * @return array 
    */ 
    public function via($notifiable) 
    { 
     return ['database']; 
    } 

    /** 
    * Get the array representation of the notification. 
    * 
    * @param mixed $notifiable 
    * @return array 
    */ 
    public function toArray($notifiable) 
    { 
     return [ 
      'asset_id' => $this->asset->id 
     ]; 
    } 
} 

編輯2

如果有人可以建議在這個時候如何做一些錯誤檢查,那可能會有所幫助。由於代碼在服務器上是異步的,因此它不會將數據返回給客戶端,並且當我嘗試將其獲取到Log時,似乎並未在陷入錯誤之前這樣做。

如何在這種情況下進行調試?

我看過框架的source code,並不知道$ user屬性來自哪裏。我認爲它與$event->notifiable綁定到User模型有關,但如果它從應用程序內的所有受影響用戶正確觸發,爲什麼它的屬性在此上下文中爲undefined

請協助,謝謝。

+0

你能告訴我們你的NotificationSent事件嗎? –

+1

@EduardoPacios它是框架代碼 - 見這裏(https://github.com/laravel/framework/blob/bd352a0d2ca93775fce8ef02365b03fc4fb8cbb0/src/Illuminate/Notifications/Events/NotificationSent.php) –

+0

我運行這個通知類和工作以及,如果你沒有在用戶拋出異常時使用Notifiable trait,像這樣:BadMethodCallException:調用未定義的方法Illuminate \ Database \ Query \ Builder :: routeNotificationFor(),但是你的錯誤是必須的,請設置隊列同步和測試值$ event – honarkhah

回答

2

這是一個奇怪的問題。當你發現自己的時候,Laravel並沒有在該對象本身上設置一個$user屬性,所以還需要其他的東西。這裏是我的認識過程:

  1. Notification::send() - >排隊NewAsset爲每個用戶通知
  2. 出隊內部的工作爲NewAsset通知 - >發送通知
  3. 消防NotificationSent事件 - >排隊NotificationListener處理

此處似乎出現錯誤:

  • 出列內部作業爲NotificationListener處理機 - >手柄事件
  • 調度作業爲SendEmail [排隊如果ShouldQueue]
  • [出隊的工作爲SendEmail如果ShouldQueue] - >發送通知電子郵件
  • 正如你所看到的,當通知的入隊和出隊時有很多序列化和反序列化。在隊列中反序列化NotificationSent事件時,似乎框架試圖設置$user屬性,但是如果沒有完整的堆棧跟蹤,很難從問題中分辨出來,並且我不確定什麼將$user添加到序列化數據中,而沒有更多的代碼可見性。

    下面是一些調試建議嘗試:

    設置QUEUE_DRIVERsync

    這可以防止框架的事件系統從序列化事件的數據。如果通知電子郵件沒有任何錯誤地發送,那麼我們知道某處的自定義代碼正在爲事件添加$user屬性。

    檢查序列化隊列中的數據:

    這不是從哪個隊列驅動應用程序使用的問題清楚。如果你是而不是使用sync,我們可以看看隊列中的待處理作業,試圖找出差異(在數據庫中,redis等)。

    1. 停止所有隊列工作。
    2. 通過應用程序觸發通知。
    3. 運行php artisan queue:work --once手動處理一個作業,直到排隊的作業運行並觸發NotificationSent事件。
    4. 檢查隊列創建的作業處理NotificationSent事件

    我們也可以用這種方法在隊列中的作業,因爲在前臺運行artisan queue:work --once轉儲使用dd()數據。

    不要排隊了NotificationSent事件處理

    由於通知已經配置在排隊的後臺作業來處理,我們並不一定需要排隊的通知事件處理爲好。嘗試刪除ShouldQueue接口,看看是否可以解決問題。

    正如其他評論者所提到的,使用Laravel的Mail Notifications可以更好地解決此問題,它完全不需要單獨的NotificationSent事件處理程序。