46

Have you seen this lovely error while working in Laravel?

Method Illuminate\View\View::__toString() must not throw an exception

I have seen it and it's incredibly annoying. I have found out two reasons why this error gets thrown. I just want to help people not take hours and hours of time.

View answers & situations below. :)

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
cbloss793
  • 1,555
  • 4
  • 19
  • 30

5 Answers5

81

There is a very simple solution: don't cast View object to a string.

Don't: echo View::make('..'); or echo view('..');

Do: echo View::make('..')->render(); or echo view('..')->render();

For PHP version <7.4 By casting view, it uses __toString() method automatically, which cannot throw an exception. If you call render() manually, exceptions are handled normally. This is the case if there is an error in the view - laravel throws an exception.

It's fixed in PHP >=7.4 you should not encounter this issue: https://wiki.php.net/rfc/tostring_exceptions.

For PHP version <7.4: This actually is a PHP limitation, not Laravels. Read more about this "feature" here: https://bugs.php.net/bug.php?id=53648

Mārtiņš Briedis
  • 17,396
  • 5
  • 54
  • 76
6

Situation 1: Trying to print out a value in an array.

Answer 1: Try printing out the array. Are you sure it's an array? I've gotten this error when it was an object instead of an array. Try doing a print_r and seeing what you get.

Situation 2: You have this associated array like this:

Array
    (
        [post_id] => 65
        [post_text] => Multiple Images!
        [created_at] => 2014-10-23 09:16:46
        [updated_on] => 
        [post_category] => stdClass Object
            (
                [category_label] => Help Wanted
                [category_code] => help_wanted
            )

        [employee_full_name] => Sam Jones
        [employee_pic] => /images/employee-image-placeholder.png
        [employee_email] => jon@gmail.com
        [post_images] => Array
            (
                [0] => stdClass Object
                    (
                        [image_path] => 9452photo_2.JPG
                    )

                [1] => stdClass Object
                    (
                        [image_path] => 8031photo_3.JPG
                    )

            )

    )

When you try to access post_images array directly within a View, it throws an error. No. Matter. What. You. Do.

Answer 2: Check in all the places where you are calling the View. What happened here is that I was trying to access the same view somewhere else in an area where I wasn't giving the post_images array. Took FOREVER to figure out.

I hope this helps someone else. :) I just know the error I kept getting didn't help me anywhere.

cbloss793
  • 1,555
  • 4
  • 19
  • 30
  • What is this array you're talking about? – MaximeBernard Nov 25 '14 at 18:16
  • 1
    @MaximeBernard, this was just an example. I've gotten this error many times sense I posted this. Every time, it was because I tried to call a value in a View, but didn't set it in the Controller each time I called the view. Such an annoying error! – cbloss793 Nov 25 '14 at 22:05
  • Great!! Glad to hear that! :) – cbloss793 Nov 26 '14 at 17:32
  • I'm getting kinda the second situation, I can access the item with no hasMany relations, but not the items with a hasMany relation, like I can't echo them out even, if I don't try to it works, I ctrl F searched my whole project but im only trying to make that view in only one place. It gives the error if I try echo those elements. – Jahanzeb Khan Dec 22 '14 at 17:18
  • @JahanzebKhan, are you trying to echo or print_r? Both are very different. – cbloss793 Dec 22 '14 at 17:55
  • echo, I see that you're not supposed to echo an array, but one other problem I'm still running into is if I want a view within a view, then trying to echo that view causes that error, how do you output a view within a view, I tried seaching but couldn't find how. – Jahanzeb Khan Dec 22 '14 at 18:00
  • 1
    @JahanzebKhan, I've seen a view within a view done a couple different ways. Here's one of the ways: http://stackoverflow.com/questions/17227969/laravel-4-including-a-partial-view-within-a-view-without-using-blade-templa Remember to submit the data that is require for the sub view. Data from the parent view does NOT go into the child view. – cbloss793 Dec 22 '14 at 19:24
  • Thank you so much! I know it's probably simple to search up but I just couldn't find it anywhere! – Jahanzeb Khan Dec 22 '14 at 22:36
  • @JahanzebKhan you are welcome! Sometimes it's hard to find the right info if you can't find the correct words. Or at least that's what I've experienced. – cbloss793 Dec 22 '14 at 23:12
0

I encountered error like this when an object in my case $expression = new Expression(); is the same as the parameter variable submitExpression($intent, $bot_id, **$expression**){ check below code for more details.

private function submitExpression($b_id, $expression){
   $expression = new Expression();
   $expression->b_id = $b_id;
   $expression->expression = $expression;
   $expression->save();

}

so I changed the above code to something like

private function submitExpression($b_id, $statement){      
   $expression = new Expression();
   $expression->b_id = $b_id;
   $expression->expression = $statement;
   $expression->save(); 
}

and everything was working fine, hope you find this helpful.

Solar
  • 870
  • 9
  • 18
0

My problem was finding out where exactly View::__toString() was being called in my code, so that I could fix it with using render() (as the other answers suggest).

To find it, temporarily edit vendor/laravel/framework/src/Illuminate/View/View.php, adding logging of the current stack trace:

public function __toString()
{
    // Next line added temporarily to debug.
    logger("This causes the '__toString() must not throw an exception' problem: " 
        . (new \Exception())->getTraceAsString());
    return $this->render();
}
Jan Żankowski
  • 8,690
  • 7
  • 38
  • 52
-1

a similar error is:

FatalErrorException in FooController.php line 0: Method App\Models\Foo::__toString() must not throw an exception

and it was just a bad assignment: $foo.= new Foo;

instead of: $foo = new Foo;

  • Very true! Good call! – cbloss793 Feb 26 '18 at 15:58
  • This is not really the explanation. What happens here is that you were concatenating a class with a variable which triggers the `__toString()` method call on the Foo instance. If the `__toString()` call causes an exception somewhere inside, you will see this message. – Mārtiņš Briedis Jul 23 '18 at 13:03