Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ConflictException
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
2 / 2
2
100.00% covered (success)
100.00%
1 / 1
 getStatusCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace App\Domain\Exception;
6
7use RuntimeException;
8
9/**
10 * Thrown when the request is well-formed and would normally be valid, but
11 * conflicts with the *current state* of the target resource.
12 *
13 * The mental test for choosing between this and {@see ValidationException}
14 * (both target HTTP 4xx codes for "we can't process this"):
15 *
16 *   "Could the same request body succeed if I tried again later, against the
17 *    same resource, after some state change?"
18 *
19 *   - If yes  → ConflictException (409) — state-driven, might resolve
20 *   - If no   → ValidationException (422) — values themselves are wrong
21 *
22 * Examples (state conflicts):
23 *   - "Cannot approve a loan with status 'approved'" — loan state conflict
24 *   - "Cannot transact on a frozen account" — account state conflict
25 *   - "Error log is already resolved" — resource state conflict
26 *   - "Cannot delete your own account" — actor identity conflict
27 *
28 * Maps to HTTP 409 Conflict.
29 */
30final class ConflictException extends RuntimeException implements HttpStatusException
31{
32    public function getStatusCode(): int
33    {
34        return 409;
35    }
36
37    public function getTitle(): string
38    {
39        return 'Conflict';
40    }
41}