Skip to content

Comments

feat: add UniqueConstraintViolationException#9979

Open
michalsn wants to merge 8 commits intocodeigniter4:4.8from
michalsn:feat/unique-exception
Open

feat: add UniqueConstraintViolationException#9979
michalsn wants to merge 8 commits intocodeigniter4:4.8from
michalsn:feat/unique-exception

Conversation

@michalsn
Copy link
Member

Description
This PR adds:

  • UniqueConstraintViolationException (extends DatabaseException), thrown on duplicate key violations across all database drivers
  • $db->getLastException(): ?DatabaseException - when DBDebug is false, exceptions are not thrown. This method provides a reliable way to inspect the type of failure, since raw error codes from $db->error()['code'] differ across drivers
  • DatabaseException::getDatabaseCode(): int|string - exposes the native driver error code on the exception itself, as getCode() is constrained to int by PHP Throwable interface and cannot carry string SQLSTATE codes

getLastException() is intentionally a transitional API. The long-term direction is to drop DBDebug = false entirely (v5 ?), leaving exceptions as the only error signalling mechanism - consistent with how every other major PHP framework handles database errors.

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication)
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@michalsn michalsn added enhancement PRs that improve existing functionalities database Issues or pull requests that affect the database layer 4.8 PRs that target the `4.8` branch. labels Feb 21, 2026
@michalsn michalsn changed the title feat: add UniqueConstraintViolationException and getLastException() feat: add UniqueConstraintViolationException Feb 21, 2026
@michalsn michalsn added the breaking change Pull requests that may break existing functionalities label Feb 22, 2026
@paulbalandan paulbalandan deleted the branch codeigniter4:4.8 February 22, 2026 10:37
@paulbalandan paulbalandan reopened this Feb 22, 2026
ClassPropertyAssignToConstructorPromotionRector::class => [
__DIR__ . '/system/Database/BaseResult.php',
__DIR__ . '/system/Database/RawSql.php',
__DIR__ . '/system/Database/Exceptions/DatabaseException.php',
Copy link
Member

Choose a reason for hiding this comment

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

Is this related to the $databaseCode property? If yes, why not proceed to promote it as it is new?

Copy link
Member Author

Choose a reason for hiding this comment

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

Rector was proposing this:

public function __construct(string $message = '', protected int|string $databaseCode = 0, ?Throwable $previous = null)

Although named parameters are not part of our BC promise, this class extends RuntimeException, and its constructor defines the second argument as $code. So changing this introduces an inconsistency with the parent signature without providing a meaningful benefit.

Copy link
Member

Choose a reason for hiding this comment

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

I see. Why not just make the constructor parameter as $databaseCode already, so that it would not clash with $code which do not accept any native type. Like in https://3v4l.org/hS5D0#vnull

@github-actions github-actions bot added the stale Pull requests with conflicts label Feb 23, 2026
@github-actions
Copy link

👋 Hi, @michalsn!

We detected conflicts in your PR against the base branch 🙊
You may want to sync 🔄 your branch with upstream!

Ref: Syncing Your Branch

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. breaking change Pull requests that may break existing functionalities database Issues or pull requests that affect the database layer enhancement PRs that improve existing functionalities stale Pull requests with conflicts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants