Skip to content

Bug: CodeIgniter\Debug\Exceptions::exceptionHandler() sending header causes error if headers already sent #5679

Description

@sclubricants

PHP Version

8.0

CodeIgniter4 Version

4.1.8

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

apache

Database

No response

What happened?

If for some reason the application has already sent headers it causes another error in the exception handler and fails to properly handle this circumstance. This allows php to output error in production environment.

Steps to Reproduce

In a controller add the following lines:

echo 'Some output<br>';
flush();
setcookie("printer", 37); 
return;

Expected Output

It is expected to receive an error that you cannot modify headers because they are already sent.

However if in production or development environments the error is dumped by php as well as an additional similar error caused in the call to header() in CodeIgniter\Debug\Exceptions::exceptionHandler()

        if (! is_cli()) {
            $this->response->setStatusCode($statusCode);
            header(sprintf('HTTP/%s %s %s', $this->request->getProtocolVersion(), $this->response->getStatusCode(), $this->response->getReasonPhrase()), true, $statusCode);

            if (strpos($this->request->getHeaderLine('accept'), 'text/html') === false) {
                $this->respond(ENVIRONMENT === 'development' ? $this->collectVars($exception, $statusCode) : '', $statusCode)->send();

                exit($exitCode);
            }
        }

The screen as well as log files show:

CRITICAL - 2022-02-11 11:32:34 --> Cannot modify header information - headers already sent
#0 [internal function]: CodeIgniter\Debug\Exceptions->errorHandler(2, 'Cannot modify h...', 'C:\\xampp\\portal...', 16)
#1 C:\xampp\portal\app\Controllers\Admin\Test.php(16): setcookie('printer', '37')
#2 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(825): App\Controllers\Admin\Test->index()
#3 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(412): CodeIgniter\CodeIgniter->runController(Object(App\Controllers\Admin\Test))
#4 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(320): CodeIgniter\CodeIgniter->handleRequest(NULL, Object(Config\Cache), false)
#5 C:\xampp\portal\public\index.php(79): CodeIgniter\CodeIgniter->run()
#6 {main}
CRITICAL - 2022-02-11 11:32:34 --> Uncaught ErrorException: Cannot modify header information - headers already sent in C:\xampp\portal\vendor\codeigniter4\framework\system\Debug\Exceptions.php:115
Stack trace:
#0 [internal function]: CodeIgniter\Debug\Exceptions->errorHandler(2, 'Cannot modify h...', 'C:\\xampp\\portal...', 115)
#1 C:\xampp\portal\vendor\codeigniter4\framework\system\Debug\Exceptions.php(115): header('HTTP/1.1 500 In...', true, 500)
#2 [internal function]: CodeIgniter\Debug\Exceptions->exceptionHandler(Object(ErrorException))
#3 {main}
  thrown
#0 [internal function]: CodeIgniter\Debug\Exceptions->shutdownHandler()
#1 {main}

Anything else?

Its a messy situation I know.. Not sure the best way to handle it. If we suppress the second error by using @Header() at least the page will continue to render in development and in production will render error page instead of outputting errors.

        if (! is_cli()) {
            $this->response->setStatusCode($statusCode);
            @header(sprintf('HTTP/%s %s %s', $this->request->getProtocolVersion(), $this->response->getStatusCode(), $this->response->getReasonPhrase()), true, $statusCode);

            if (strpos($this->request->getHeaderLine('accept'), 'text/html') === false) {
                $this->respond(ENVIRONMENT === 'development' ? $this->collectVars($exception, $statusCode) : '', $statusCode)->send();

                exit($exitCode);
            }
        } 

Then our log outputs only the first error:

CRITICAL - 2022-02-11 11:52:34 --> Cannot modify header information - headers already sent
#0 [internal function]: CodeIgniter\Debug\Exceptions->errorHandler(2, 'Cannot modify h...', 'C:\\xampp\\portal...', 16)
#1 C:\xampp\portal\app\Controllers\Admin\Test.php(16): setcookie('printer', '37')
#2 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(825): App\Controllers\Admin\Test->index()
#3 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(412): CodeIgniter\CodeIgniter->runController(Object(App\Controllers\Admin\Test))
#4 C:\xampp\portal\vendor\codeigniter4\framework\system\CodeIgniter.php(320): CodeIgniter\CodeIgniter->handleRequest(NULL, Object(Config\Cache), false)
#5 C:\xampp\portal\public\index.php(79): CodeIgniter\CodeIgniter->run()
#6 {main}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugVerified issues on the current code behavior or pull requests that will fix them

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions