-
Notifications
You must be signed in to change notification settings - Fork 11.7k
Closed
Description
- Laravel Version: 10.2.0
- PHP Version: 8.1.11
- Database Driver & Version: N/A
Description:
When json encoding a model using toJson, if there was a previous json error, the model fails because of how it detects json errors.
Here is the toJson code in Illuminate\Database\Eloquent\Model.php:
/**
* Convert the model instance to JSON.
*
* @param int $options
* @return string
*
* @throws \Illuminate\Database\Eloquent\JsonEncodingException
*/
public function toJson($options = 0)
{
$json = json_encode($this->jsonSerialize(), $options);
if (json_last_error() !== JSON_ERROR_NONE) {
throw JsonEncodingException::forModel($this, json_last_error_msg());
}
return $json;
}The problem occurs if, somewhere else in the software, an error was thrown in a json_encode or json_decode call, even if called with the @ operator.
I would suggest changing to something like this:
public function toJson($options = 0)
{
try {
$json = json_encode($this->jsonSerialize(), $options & JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
throw JsonEncodingException::forModel($this, $e->getMessage());
}
return $json;
}or this:
public function toJson($options = 0)
{
if (json_last_error() !== JSON_ERROR_NONE) {
json_encode("");
}
$json = json_encode($this->jsonSerialize(), $options);
if (json_last_error() !== JSON_ERROR_NONE) {
throw JsonEncodingException::forModel($this, json_last_error_msg());
}
return $json;
}Steps To Reproduce:
Do the following:
composer create-project laravel/laravel laravel-json-bug
cd laravel-json-bug
php artisan make:model Test --all
Create a test route in web.php:
Route::get('/test', [TestController::class, 'index']);Edit TestController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Test;
class TestController extends Controller
{
public function index()
{
$testModel = new Test();
$testModel->foo = 'bar';
@json_decode('[this is invalid json]');
return view('test', ['test' => $testModel]);
}
}Now create a view test.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
</head>
<body>
<script>console.log(@js($test));</script>
</body>
</html>You will be greeted with the following error:
Error encoding model [App\Models\Test] with ID [] to JSON: Syntax error
Metadata
Metadata
Assignees
Labels
No labels
