Создание блога

firep91613

Новичок
Плохо ли использовать try catch в методе модели-репозитория и в методе контроллера одновременно? Допустим, удаление же это несколько связанных операций. Я сделал в модели-репозитории транзакцию с try catch. В контроллере, в случае успешного удаления надо сделать редирект с одним флеш сообщеним, а в случае ошибки удаления - с другим сообщением. Ну и исключение тоже надо перехватить.
 

AmdY

Пью пиво
Команда форума
Плохо ли использовать try catch в методе модели-репозитория и в методе контроллера одновременно? Допустим, удаление же это несколько связанных операций. Я сделал в модели-репозитории транзакцию с try catch. В контроллере, в случае успешного удаления надо сделать редирект с одним флеш сообщеним, а в случае ошибки удаления - с другим сообщением. Ну и исключение тоже надо перехватить.
Можно использовать. Но тебе стоит рассмотреть вариант с глобальной ловлей исключений на уровне выше контроллера. Посмотри как делают в Laravel https://laravel.com/docs/master/errors
 

firep91613

Новичок
Как по людски идентифицировать исключение? Бросается, к примеру, такой эксепшен:
PHP:
throw new CategoryException("Ошибка при удалении категории {$e->getMessage()}", $id);
Нужно узнать, что это именно была ошибка при удалении. Я сделал, пока что так:
PHP:
public function isDeleteError(): bool
{
    return str_contains($this->getMessage(), 'Ошибка при удалении категории');
}
Есть ощущение, что это говно-код.
 

AmdY

Пью пиво
Команда форума
Почитай документацию. Исключения проверяются по типу прямо в catch или внутри него через instanceof
Код:
try {
...
    throw new CategoryException("Ошибка при удалении категории", $id);
} catch(CategoryException $e) {
    echo "Исключение CategoryException с текстом:  {$e->getMessage()}";
} catch(\Throwable $e) {
    echo "Это НЕ CategoryException с текстом:  {$e->getMessage()}";
}
Код:
try {
...
    throw new CategoryException("Ошибка при удалении категории", $id);
} catch(\Throwable $e) {
    if ($e instanceof CategoryException) {
        echo "Это CategoryException с текстом:  {$e->getMessage()}";
    } else {
        echo "Это НЕ CategoryException с текстом:  {$e->getMessage()}";
    }
}
 

firep91613

Новичок
Почитай документацию. Исключения проверяются по типу прямо в catch или внутри него через instanceof
Я наверно не правильно выразился. Там же в Laravel исключения можно ловить в bootstrap/app.php или в самом классе в методе render. И ошибки могут быть разные. При удалении, обновлении, создании, к примеру. Я так пока что сделал, это работает. Но сам подход очень сомнительный.
PHP:
<?php

namespace App\Exceptions;

class CategoryException extends \Exception
{
    public function __construct(string $message, protected ?int $categoryId = null)
    {
        parent::__construct($message);
    }

    public function getCategoryId(): int
    {
        return $this->categoryId;
    }

    public function isDeletionError(): bool
    {
        return str_contains($this->getMessage(), 'Ошибка при удалении категории');
    }

    public function isUpdateError(): bool
    {
        return str_contains($this->getMessage(), 'Ошибка при обновлении категории');
    }

    public function isCreateError(): bool
    {
        return str_contains($this->getMessage(), 'Ошибка при создании категории');
    }
}
PHP:
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (CategoryException $e) {
        if ($e->isDeletionError()) {
            return redirect()->route('admin.categories.show', $e->getCategoryId())->with('error', $e->getMessage());
        }

        if ($e->isUpdateError()) {
            return redirect()->route('admin.categories.edit', $e->getCategoryId())->with('error', $e->getMessage());
        }

        if ($e->isCreateError()) {
            return redirect()->route('admin.categories.create')->with('error', $e->getMessage());
        }

        return false;
    });
})
 

AmdY

Пью пиво
Команда форума
Зачему ты так делаешь? Сразу же видно дублирование.
Ты можешь например завести отдельный тип исключений RedirectException и тогда делать общую логику

PHP:
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (RedirectException $e) {
            return redirect()->route($e->getRoute(), ...$e->getParams())->with('error', $e->getMessage());
    });
})
 

AnrDaemon

Продвинутый новичок
Вишенка.
PHP:
        set_exception_handler(function (\Throwable $e) use ($ex_log) {
            if (\PHP_SAPI !== 'cli') header("Content-Type: application/json; charset=UTF-8");
            $ex_log($e);
            try {
                throw $e;
            } catch (\mysqli_sql_exception | \PDOException $e) {
                die(json_encode(["result" => -1, "error" => "Database operation failed, see logs"]));
            } catch (PlatformException $e) {
                if ($e->getCode() > 99 && \PHP_SAPI !== 'cli') {
                    http_response_code($e->getCode());
                }
                die(json_encode($e->__toApiResponse()));
            } catch (\Throwable $e) { // Catch-all fallback
                $code = $e->getCode() ?: (strpos($e->getMessage(), "logout") ? -2 : -1);
                die(json_encode(["result" => $code, "error" => $e->getMessage()]));
            }
        });
 
Сверху