Welcome Guest, Not a member yet? Register   Sign In
Supports stopping the controller at any position
#1

Hi,

Would be nice to support stopping the controller at any position.
For now, I have to return $output in Controller's public method. See https://codeigniter.com/user_guide/outgo...onses.html
PHP Code:
<?php

namespace App\Controllers;

use 
CodeIgniter\API\ResponseTrait;
use 
CodeIgniter\Controller;

class 
Users extends Controller
{
    use ResponseTrait;

    public function createUser()
    {
        $model = new UserModel();
        $user  $model->save($this->request->getPost());

        // Respond with 201 status code
        return $this->respondCreated();
    }


But it's hard to return $output in any other position which is not in Controller's public method directly.
For example:
PHP Code:
public function createUser()
{
    $status $this->checkPost($this->request->getPost());
    if ($status !== true) return $status;

    $model = new UserModel();
    $user  $model->save($this->request->getPost());

    // Respond with 201 status code
    return $this->respondCreated();
}

protected function 
checkPost()

    $checkResult false;
    if (! $checkResult) {
        return $this->fail('Check error');
    }

    return true;

I have to return as above if I want to stop controller in checkPost method.

If I can stop controller by using an exception, that would be very nice!
For example,
PHP Code:
protected function checkPost()
{
    $checkResult false;
    if (! $checkResult) {
        $output $this->fail('Check error');
        throw RespondException::forControllerStopped($output);
    }

    return true;


To support RespondException, need to modify  runController method in Codeigniter.php
PHP Code:
protected function runController($class)
{
    // This is a Web request or PHP CLI request
    $params $this->router->params();

    // $output = method_exists($class, '_remap')
    //    ? $class->_remap($this->method, ...$params)
    //    : $class->{$this->method}(...$params);

    try {
        $output method_exists($class'_remap')
            $class->_remap($this->method, ...$params)
            $class->{$this->method}(...$params);
    } catch (RespondException $re) {
        $output $re->getOutput();
    }

    $this->benchmark->stop('controller');

    return $output;


Please can we support this function?
Thank you!
Reply
#2

Use Exceptions for Exceptional Problems. -- The Pragmatic Programmer
Reply
#3

(This post was last modified: 05-08-2023, 08:47 PM by devinLin.)

(05-08-2023, 08:41 PM)kenjis Wrote: Use Exceptions for Exceptional Problems. -- The Pragmatic Programmer

Any idea to stop controller at any position?
Reply
#4

I agree with this description - breaking out of a controller in CI4 is hard due to the double-nesting approach. CI3 was cleaner in this respect.
The approach I am using is currently to have a set_exception_handler() in my BaseController and then throw exceptions for everything.
In my exception handler I use the exit() statement as described here: https://codeigniter.com/user_guide/gener...ror%20page
Reply
#5

I think the checkPost() method is not good.
It should return boolean.

> breaking out of a controller in CI4 is hard

Yes, because a controller must return a response.
Reply
#6

I personally believe that PageNotFound and Redirect are no exception.
Therefore, I am not in favor of more exceptions for non-exceptional situations.

If your case is really exceptional, you can use any exception as you like anywhere in the controller.

Why do you want to stop the controller at any position?
The controller's job is to return a response.
Reply
#7

(This post was last modified: 05-08-2023, 09:29 PM by tgix.)

(05-08-2023, 09:15 PM)kenjis Wrote: I think the checkPost() method is not good.
It should return boolean.

> breaking out of a controller in CI4 is hard

Yes, because a controller must return a response.

Just thinking aloud here. Using a static function returning a response would perhaps make the code cleaner:

PHP Code:
if (true) {
  return ControllerBreak::error('Check error');

Reply
#8

(This post was last modified: 05-08-2023, 09:56 PM by iRedds.)

Use Laravel or wait for CI 4.4, it adds the ability for custom exception handling.

In my opinion, the framework has hit a dead end. Any improvements turn into breaking changes, and the core team is conservative. They prefer "clean route config" or a dark theme in the documentation. Due to the low activity of the community, some initiatives that contradict the visions of the core team are ignored.

If you don't want to wait for 4.4, you can implement exception handling yourself.
Reply
#9

(This post was last modified: 05-08-2023, 10:11 PM by devinLin.)

(05-08-2023, 09:26 PM)kenjis Wrote: I personally believe that PageNotFound and Redirect are no exception.
Therefore, I am not in favor of more exceptions for non-exceptional situations.

If your case is really exceptional, you can use any exception as you like anywhere in the controller.

Why do you want to stop the controller at any position?
The controller's job is to return a response.

1. I want to set an error response and stop executing any subsequent codes of controller as soon as I find a business error.
So that I don't need to return an error response at the public method of controller, because return an error response is very cumbersome if there are many cases of error and deep level function calls

2. Look at my example above, RespondException is not a real exception, just a way to stop controller. I can catch the RespondException myself
PHP Code:
public function createUser()
{
    try {
        $status $this->checkPost($this->request->getPost());
        if ($status !== true) return $status;

        $model = new UserModel();
        $user  $model->save($this->request->getPost());

        // Respond with 201 status code
        return $this->respondCreated();
    } catch (RespondException $re) {
        $output $re->getOutput();
        return $output;
    }


But I have to catch RespondException in every public method.

3. I don't want to catch RespondException in every public method. 
So I am asking if we can catch RespondException in runController method in Codeigniter.php file
(Add system/Exceptions/RespondException.php)

RespondException just a preliminary idea
Reply
#10

You can extend Codeigniter.php.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB