Skip to content

refactor(log): return int from HandlerInterface::handle() - #10578

Open
Alexandros-Pallis wants to merge 1 commit into
codeigniter4:4.8from
Alexandros-Pallis:feature/change-logger-handler-interface-behavior
Open

Alexandros-Pallis wants to merge 1 commit into
codeigniter4:4.8from
Alexandros-Pallis:feature/change-logger-handler-interface-behavior

Conversation

@Alexandros-Pallis

Copy link
Copy Markdown

Follow-up to #10560 , implementing the approach agreed there for 4.8.

Problem

Logger::log() stops running handlers when one returns false from handle(). The built-in handlers (FileHandler,
ErrorlogHandler) return false when a write fails, so one failing handler (e.g. FileHandler with bad permissions on
the log directory) silently prevents every handler after it from logging. A configured ErrorlogHandler fallback never
runs and the log entry is lost.
false was doing two jobs: "the write failed" and "stop the chain". A handler had no way to report one without
triggering the other.

Change

HandlerInterface::handle() now returns int instead of bool, as suggested by @paulbalandan:

  • HandlerInterface::RESULT_CONTINUE (1): the remaining handlers run.
  • HandlerInterface::RESULT_STOP (2): the chain stops.

Logger::log() breaks only on RESULT_STOP. Any other value continues.

The built-in handlers (FileHandler, ErrorlogHandler, ChromeLoggerHandler) and the test TestHandler always return
RESULT_CONTINUE, including when a write fails. That fixes the original problem.

Behavior changes

  • A FileHandler that cannot write no longer stops later handlers. On develop it did.
  • The built-in handlers no longer expose write failure through their return value. Nothing in the framework consumed it
    apart from the chain-stopping break, but code calling handle() directly and checking the result would no longer see
    failures.

Breaking change

Custom log handlers that override handle() must change the return type from bool to int and return the new constants (true -> RESULT_CONTINUE, false -> RESULT_STOP). A handler still declaring : bool is incompatible with the interface and causes a fatal error when the class loads. Migration steps are in upgrade_480.rst.

Tests

  • LoggerTest: a handler returning RESULT_CONTINUE lets the next handler run; one returning RESULT_STOP prevents it.
  • FileHandlerTest: a file that cannot be opened returns RESULT_CONTINUE.
  • Existing handler tests now assert RESULT_CONTINUE instead of true.
  • tests/system/Log passes (61 tests), also in random order.

Docs

  • upgrade_480.rst: return type change, constants, before/after example.
  • v4.8.0.rst: Interface Changes entry and a Changes entry for the FileHandler behavior.
  • general/logging.rst: note on handler order and return values.

Checklist

  • I have read the CONTRIBUTING guide
  • My code follows the code style of this project
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • This PR is on a custom branch and not develop

Returning false stopped the handler chain, and built-in handlers
returned false on write failure. A failing FileHandler (e.g. bad
permissions) silently blocked later handlers such as ErrorlogHandler.

handle() now returns RESULT_CONTINUE or RESULT_STOP. Built-in handlers
always return RESULT_CONTINUE, so a write failure no longer stops the
chain. Logger only stops on RESULT_STOP.

BREAKING CHANGE: custom log handlers must change the handle() return
type from bool to int and return HandlerInterface::RESULT_CONTINUE
(was true) or RESULT_STOP (was false). A handler still declaring
`: bool` is a fatal error at class load. See upgrade_480.rst.
@carson-codeigniter4 carson-codeigniter4 Bot added 4.8 PRs that target the `4.8` branch. refactor Pull requests that refactor code labels Sep 21, 2026

@neznaika0 neznaika0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks logical, but now we practically have no option to stop the handler - result is always returned to continue processing.

Perhaps, after these changes, stopping is not required at all, in which case, what’s the point of the new constants?

This branch has not been deployed

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

Labels

4.8 PRs that target the `4.8` branch. refactor Pull requests that refactor code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants