Bonjour, je suis la formation citée ci-haut et je viens de terminer les modules qui me concernent (Exit donc la partie E-Commerce) et e terminant je viens de rencontrer quelques erreurs liées aux exceptions.

Ce que je fais

  1. Je vais éditer un article qui n'existepas -:) (id de l'article) et j'obtiens une erreur ; No Message dans NoRecordException
  2. Erreur Similaire je crois quand je vais afficher l'article qui n'existe pas mais cette fois l'erreur c'est dans le ForbidenMiddleware : None returned in ForbiddenMiddlewar
  3. Je vais essayer tout bêtement de lister mes articles (Parties admin) à une page ?p=4000 page qui n'existe pas bien sûr et j'ai une erreur qui est retournée
Entourez votre code pour bien le mettre en forme

Ce que je veux

  1. Avoir un message d'erreur disant que l'article n'existe pas
  2. Avoir un message d'erreur disant que l'article n'existe pas et être redirigée vers la page index
  3. Avoir un message d'erreur disant la page n'existe pas

Ce que j'obtiens

Comme dit ci-haut

  1. ... j'obtiens une erreur ; No Message dans NoRecordException
  2. ... l'erreur c'est dans le ForbidenMiddleware : None returned in ForbiddenMiddlewar
  3. ... j'ai une erreur qui est retournée

7 réponses


jobson
Auteur
Réponse acceptée

Merci pour vos orientations, au fait au départ je n'y connaissais pas grand-chose mais quand vous m'avez parlé de try catch, j'ai un peu cherché de ce côte. Et j'ai trouvé, le problème c'est que dans ma fonction findWithCategory je n'avais nulle part throw une erreur, et en cherchant j'ai encore trouvé sur le site une vidéo expliquant bien le principe https://www.grafikart.fr/tutoriels/exception-throw-try-catch-529 et c'est bon ça marche.
et le morceau de code c'est presque le même

public function __invoke(Request $request)
    {
        try {
            $slug = $request->getAttribute('slug');
            $post = $this->postTable->findWithCategory($request->getAttribute('id'));
            $categories = $this->categoryTable->makeQuery();
            if ($post->slug !== $slug) {
                return $this->redirect('blog.show', [
                    'slug' => $post->slug,
                    'id' => $post->id
                ]);
            }
            return $this->renderer->render('@blog/show', [
                'post' => $post,
                'categories' => $categories
            ]);
        } catch (NoRecordException $e) {
            $this->flash->error("Vous essayez d'afficher un article qui n'existe pas");
            return new RedirectResponse('/blog');
        }
    }

Bonsoir,
Pour l'erreur : No message dans NoRecordException .
Si je comprends bien , tu testes ton code en recherchant un article dont l'id n'existe pas et dans ce cas ton code te jette (throw) une nouvelle erreur de type NorecordException.
Si je ne me trompe pas , il semblerait que l'erreur soit soulevée dans ton cas par la méthode fetchOrFail() dans Query.php.
Cependant aucun message n'a été défini pour cette exception .
Pour moi, il te suffit de gérer ton exception :
-soit en lui définissant un message par défaut ( pas bien :D)
-soit par un 'try .... catch (NoRecordException...)' et lui définir un message d'erreur /une action etc
-soit en enrichissant la classe NoRecordException.

jobson
Auteur

Merci pour les réponses mais j'ai quelques soucis :

  1. Dans la 1ère solution je ne sais pas comment m'y prendre
  2. Dans la 2ème je suis un peu bloqué, est-ce aue le bloc try Catch c'est dans l'action de la page (Comme ici dans la PostIndexAction
public function __invoke(Request $request)
    {

        try {
            $params = $request->getQueryParams();
            $posts = $this->postTable->findPublic()->paginate(10, $params['p'] ?? 1);
            $categories = $this->categoryTable->makeQuery();
            return $this->renderer->render('@blog/index', compact('posts', 'categories'));
        } catch (NoRecordException $e) {
            $errors = ['article' => 'L\'aricle que vous essayez d\'afficher n\'existe pas'];
        }
        return $this->renderer->render('@blog/index', compact('errors'));
    }

Car ici, ça renvoie toujours l'erreur
ou directement dans le NoRecordException

  1. Je voudrais bien enrichir la classe, mais comment?
    Un exemple de code serait le bienvenue. Encore Merci pour la réponse.

bonsoir,
ta classe NoRecordException est elle bien chargée ? ( use ...)

jobson
Auteur

oui très bien chargée,

Par contre , le code que tu me montres ne semble pas correspondre au descriptif donné dans ton premier post où tu disais avoir une erreur quand tu cherchais à editer un article avec un Id erroné .
Le code que tu montres par contre ( si je lis bien...) correspond à la page index qui affiche la liste des catégories et des articles . Ton erreur ne provient donc pas de cette partie du code. C'est pourquoi ton try...catch ne capture pas ton exception. Si il me parait bien ecrit , il ne semble pas placer dans la bonne partie du code .

jobson
Auteur

Je m'excuse je me suis un peu trompé de classe, mais je ne sais pas vraiment ou je dois place le bloc try catch
je remontre mes erreurs :

  1. Edition d'un article qui n'existe pas me renvoie l'erreur
    Framework \ Database \ NoRecordException
    No message

    et me localise l'erreur ici

    public function fetchOrfFail()
    {
        $record = $this->fetch();
        if ($record === false) {
            throw new NoRecordException();
        }
        return $record;
    }

    La classe c'est PostCrudAction (et hérite de CrudAction)

  2. Affichage d'un article aui n'existe pas renvoie l'erreur

    Return value of App\Auth\ForbiddenMiddleware::process() must be an instance of Psr\Http\Message\ResponseInterface, none returned

    et localise l'erreur dans le ForbiddenMiddleware

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        try {
            return $handler->handle($request);
        } catch (ForbiddenException $exception) {
            return $this->redirectLogin($request);
        } catch (\TypeError $error) {
            if (strpos($error->getMessage(), User::class) !== false) {
                return $this->redirectLogin($request);
            }
        }
    }
    
    public function redirectLogin(ServerRequestInterface $request)
    {
        $this->session->set('auth.redirect', $request->getUri()->getPath());
        (new FlashService($this->session))->error('Vous devez avoir un compte administrateur pour accéder à cette page');
        return new RedirectResponse($this->loginPath);
    }

    La classe c'est PostShowAction

    public function __invoke(Request $request)
    {
        $slug = $request->getAttribute('slug');
        $post = $this->postTable->findWithCategory($request->getAttribute('id'));
        $categories = $this->categoryTable->makeQuery();
        if ($post->slug !== $slug) {
            return $this->redirect('blog.show', [
                'slug' => $post->slug,
                'id' => $post->id
            ]);
        }
        return $this->renderer->render('@blog/show', [
            'post' => $post,
            'categories' => $categories
            ]);
    }
  3. Enfin Afficher un ?p=1000 (page qui n'existe pas) renvoie l'erreur

    Pagerfanta \ Exception \ OutOfRangeCurrentPageException
    Page "1000" does not exist. The currentPage must be inferior to "2"

    et localise l'erreur dans la classe PagerFanta

    private function normalizeOutOfRangeCurrentPage($currentPage)
    {
        if ($this->getNormalizeOutOfRangePages()) {
            return $this->getNbPages();
        }
    
        throw new OutOfRangeCurrentPageException(sprintf('Page "%d" does not exist. The currentPage must be inferior to "%d"', $currentPage, $this->getNbPages()));
    }

    Encore merci pour votre assistance, j'espère que vous aller pouvoir comprendre mes preoccupations et surtout me donner des des réponses.