{"id":16674695,"url":"https://github.com/mnavarrocarter/problem-details","last_synced_at":"2026-05-12T16:37:12.182Z","repository":{"id":57018505,"uuid":"128075261","full_name":"mnavarrocarter/problem-details","owner":"mnavarrocarter","description":"A framework agnostic RFC7807 implementation","archived":false,"fork":false,"pushed_at":"2018-04-04T15:30:53.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-05T03:48:27.911Z","etag":null,"topics":["api","error-handling","exception-handling","exceptions","php","php7","problem-details","rest","rest-api","rfc7807"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mnavarrocarter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-04T14:36:18.000Z","updated_at":"2018-04-04T15:29:22.000Z","dependencies_parsed_at":"2022-08-22T20:30:53.100Z","dependency_job_id":null,"html_url":"https://github.com/mnavarrocarter/problem-details","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/mnavarrocarter/problem-details","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnavarrocarter%2Fproblem-details","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnavarrocarter%2Fproblem-details/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnavarrocarter%2Fproblem-details/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnavarrocarter%2Fproblem-details/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mnavarrocarter","download_url":"https://codeload.github.com/mnavarrocarter/problem-details/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnavarrocarter%2Fproblem-details/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32948027,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T09:19:52.626Z","status":"ssl_error","status_checked_at":"2026-05-12T09:17:33.438Z","response_time":102,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","error-handling","exception-handling","exceptions","php","php7","problem-details","rest","rest-api","rfc7807"],"created_at":"2024-10-12T12:43:56.679Z","updated_at":"2026-05-12T16:37:12.160Z","avatar_url":"https://github.com/mnavarrocarter.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"ApiException (RFC7807 Implementation)\n=====================================\n\nApiException is an **abstract exception class for php** that implements the \n[RFC7807](https://tools.ietf.org/html/rfc7807) problem details structure.\n\nIt is ment to be extended into other exception classes that define specific error\ntypes, according to the RFC.\n\n### Installing\nSimply do:\n    \n    composer require mnavarrocarter/problem-details\n\n## Usage\n\n### Creating your custom Exception Types\nFor the different problem types in your api, you must create meaningful exception\nclasses that will extend this abstract one, and override the constructor to set\nyour custom type, title and, if you want, status code.\n\n```php\n\u003c?php\n\nnamespace App\\Errors;\n\nuse MNC\\ProblemDetails\\ApiException;\n\nclass AuthenticationProblemException extends ApiException\n{\n    public function __construct(string $detail = '', array $extra = [], ?\\Throwable $previous = null)\n    {\n        $type = 'errors/authentication';\n        $title = 'Authentication Error';\n        $statusCode = 401;\n        parent::__construct($type, $title, $statusCode, $detail, $extra, $previous);\n    }\n}\n\n```\n\n### Using Factory Pattern to simplify error creation.\n\nNow, with your class created, you can use the factory pattern to quickly and simply\ncreate new instances of the custom error type you just created.\n\n```php\n\u003c?php\n\nnamespace App\\Errors;\n\nuse MNC\\ProblemDetails\\ApiException;\n\nclass AuthenticationProblemException extends ApiException\n{\n    public function __construct(string $detail = '', array $extra = [], ?\\Throwable $previous = null)\n    {\n        $type = 'errors/authentication';\n        $title = 'Authentication Error';\n        $statusCode = 401;\n        parent::__construct($type, $title, $statusCode, $detail, $extra, $previous);\n    }\n    \n    public static function invalidCredentials(array $sentCredentials)\n    {\n        return new self(\n            'Invalid credentials',\n            $sentCredentials  \n        );\n    }\n}\n\n```\n\nThen, in your client code:\n\n```php\n\u003c?php\n\nnamespace App\\Services;\n\nuse App\\Error\\AuthenticationProblemException;\n\nclass Authenticator extends ApiException\n{\n    public function authenticate(array $sentCredentials)\n    {\n        if ($this-\u003eareValidCredentials($sentCredentials)) {\n            return $this-\u003efindUser($sentCredentials);\n        }\n        throw AuthenticationProblemException::invalidCredentials($sentCredentials);\n    }\n}\n\n```\n\nThen, at your controller level, you can catch these exceptions to provide a response.\nOr, if you use frameworks like Symfony, you can configure an Exception Listener.\n\n```php\n\n\u003c?php\n\nnamespace App\\Controller;\n\nuse MNC\\ProblemDetails\\ApiException;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller;\n\nclass SomeController extends Controller\n{\n    public function someAction(Request $request)\n    {\n        try {\n            $variable = $this-\u003etryAction($request);\n        } catch (ApiException $e) {\n            return $this-\u003ejson($e, $e-\u003egetStatusCode());\n        }\n        return $variable;\n    }\n}\n```\n\nIf you noticed, the ApiException implements PHP's `\\JsonSerializable` interface. So\nit is easily serialized with a simple `json_encode()`. If you want to just normalize\nthe object, you can call the `toArray()` method.\n\n### Modifiying the implementation\n\ntldr; You can't. You can implement the interface though.\n\nThis implementation is very closed. Property visibility is hidden from you,\nand you can only interact with the properties via the public methods.\n\nAlso, the implementation methods are declared final, so you can't override them.\nThis will protect you from breaking anything, as this class is developed to always\nprovide a meaningful response by checking stuff in getters and setters.\n\nThe interface is there in case you want to create your own implementation.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnavarrocarter%2Fproblem-details","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmnavarrocarter%2Fproblem-details","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnavarrocarter%2Fproblem-details/lists"}