У Laravel есть хорошее решение для этого. В документации нам сказано сделать такое исключение при обработке в App\Exceptions\Handler
.
Очень простой пример может быть следующим:
// Your controller.
try {
$invoice = Invoice::create(['']);
return response()->json($model);
} catch (\Exception $e) {
throw new CustomException('Invoice creation failed.');
}
// app\Exceptions\Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $exception);
}
Я пытался выяснить, выдаст ли create
конкретное исключение. К сожалению, я не смог так быстро это выяснить. Если бы это было так, вы могли бы удалить try catch
и просто прослушать это конкретное исключение в методе render
.
Обновление
(не проверено)
Кроме того, вы также можете перезаписать метод save
, чтобы избежать необходимости переносить (все) вызовы метода записи в базу данных с try
и catch
.
Нам понадобится BaseModel
класс:
<?php
namespace App\Models;
use App\Exceptions\ModelSaveException;
use Illuminate\Database\Eloquent\Model as EloquentModel;
class Model extends EloquentModel
{
/**
* Save the model to the database.
*
* @param array $options
* @return bool
* @throws \App\Exceptions\ModelSaveException
*/
public function save(array $options = [])
{
try {
return parent::save($options);
} catch(\Exception $e) {
throw new ModelSaveException($this);
}
}
}
Ваш контроллер будет выглядеть чище без try catch
:
$invoice = Invoice::create(['']);
return response()->json($model);
В качестве дополнения мы можем проверить, была ли наша модель создана обновленной, сделав свойство exists
.
<?php
namespace App\Exceptions;
class ModelSaveException extends \Exception
{
/**
* ModelSaveException constructor.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function __construct($model)
{
if ($model->exists) {
parent::__construct('Failed updating model.');
} else {
parent::__construct('Failed creating model.');
}
}
}
Конечно, не забудьте продлить от вас только что созданную модель:
use App\Models\Model;
class Invoice extends Model