{"id":23789801,"url":"https://github.com/officiallysingh/problem-handler-webflux-demo","last_synced_at":"2025-10-13T03:13:18.290Z","repository":{"id":190441153,"uuid":"677769466","full_name":"officiallysingh/problem-handler-webflux-demo","owner":"officiallysingh","description":"Spring Webflux REST service for demonstrating problem handler","archived":false,"fork":false,"pushed_at":"2025-04-20T06:14:59.000Z","size":78,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-13T03:13:17.829Z","etag":null,"topics":["controller-advice","exception-handling","exceptions","problemdetails","spring-boot-3","spring-boot-webflux"],"latest_commit_sha":null,"homepage":"","language":"Java","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/officiallysingh.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-08-12T15:24:12.000Z","updated_at":"2025-04-20T06:15:02.000Z","dependencies_parsed_at":"2023-08-24T17:57:57.393Z","dependency_job_id":"85199e8d-95cc-499b-b473-6a51a00e89f6","html_url":"https://github.com/officiallysingh/problem-handler-webflux-demo","commit_stats":null,"previous_names":["officiallysingh/problem-handler-webflux-demo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/officiallysingh/problem-handler-webflux-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/officiallysingh%2Fproblem-handler-webflux-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/officiallysingh%2Fproblem-handler-webflux-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/officiallysingh%2Fproblem-handler-webflux-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/officiallysingh%2Fproblem-handler-webflux-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/officiallysingh","download_url":"https://codeload.github.com/officiallysingh/problem-handler-webflux-demo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/officiallysingh%2Fproblem-handler-webflux-demo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279014168,"owners_count":26085369,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["controller-advice","exception-handling","exceptions","problemdetails","spring-boot-3","spring-boot-webflux"],"created_at":"2025-01-01T17:16:46.458Z","updated_at":"2025-10-13T03:13:18.274Z","avatar_url":"https://github.com/officiallysingh.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Problem Handler Webflux Demo\n\n## Getting started\n\n### Docker compose\nIf you have docker installed, then simply run the application in `docker` profile by passing `spring.profiles.active=docker` \nas run time argument from your IDE.\nDepending on your current working directory in IDE, you may need to change `spring.docker.compose.file=problem-handler-webflux-demo/compose.yml`\nto `spring.docker.compose.file=compose.yml` in [**`application-docker.properties`**](src/main/resources/config/application-docker.properties)\n\nMake sure the host ports mapped in [**`Docker compose file`**](compose.yml) are available or change the ports and \ndo the respective changes in database configurations [**`application-docker.properties`**](src/main/resources/config/application-docker.properties)\n\n### Explicit Database configs\nUpdate following properties with your PostgresDB configurations\n\n```properties\nspring.r2dbc.url=${POSTGRES_URL:r2dbc:postgresql://localhost:5432/problem_webflux_db}\nspring.r2dbc.username=${POSTGRES_USER:postgres}\nspring.r2dbc.password=${POSTGRES_USER:admin}\n\nspring.flyway.url=${POSTGRES_URL:jdbc:postgresql://localhost:5432/problem_webflux_db}\nspring.flyway.user=${POSTGRES_USER:postgres}\nspring.flyway.password=${POSTGRES_PASSWORD:admin}\n```\n\nUpdate following properties with your MongoDB configurations\n```properties\nspring.data.mongodb.uri=${MONGODB_URL:mongodb://localhost:27017/problem_web_db}\n```\n## Run\nRun the main class [`ProblemWebFluxDemoApplication`](src/main/java/com/ksoot/problem/demo/ProblemWebFluxDemoApplication.java)\nand access Swagger [`Swagger`](http://localhost:8080/swagger-ui.html) at http://localhost:8080/swagger-ui.html\n\nSelect `Application` from dropdown **Select a definition**\n\n* **State** management APIs are using MongoDB, to test database constraint violations.\n* **Employee** management APIs are using PostgresDB, to test database constraint violations.\n* **Problem Demo** APIs throws exceptions explicitly.\n  Have a look at [`DemoProblemController`](src/main/java/com/ksoot/problem/demo/controller/DemoProblemController.java)\n* **State** and **Employee** management APIs are secured, so need to pass a JWT token in `Authorization` header. \nSee the lock symbol against the API in Swagger\n\n**Click on Authorize button** to pass the JWT Token. Use any valid JWT Token.\n```\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\n```\n\n* Call the APIs providing invalid inputs to make it throw exception and have a look at response.\n* Set `problem.debug-enabled=true` in [`application.properties`](src/main/resources/config/application.properties) to get the message resolvers\n  and set the messages in [`errors.properties`](src/main/resources/i18n/errors.properties) to customize the error response attributes in response.\n* Test with setting `problem.stacktrace-enabled=true` and `problem.cause-chains-enabled=true`\n  in [`application.properties`](src/main/resources/config/application.properties) to get Stacktrace and Cause in response.\n* Update [`help.html`](src/main/resources/static/problems/help.html) with any custom error description and follow the `type` url \nin error response to see the error description on help page.\n* Follow http://localhost:8080/problems/help.html to see the description of errors.\n\n\n## Examples\n**Following are example error responses in different scenarios.**\nThe error response attributes `code`, `title` and `detail` can be customized for each error by specifying\nthe same in `errors.properties` file for different error keys which you can get by setting `problem.debug-enabled=true` in `application.properties` file\n\n### Constraint violations\nMost common type of errors an application must handle\n\n#### Jakarta Constraint violations error\n\nCode\n```java\n@Valid\n@Getter\n@Setter\npublic static final class UserRequest {\n\n    @Size(min = 3, max = 10)\n    private String name;\n\n    @Size(min = 2, max = 5)\n    private String designation;\n\n    @NotNull\n    @Valid\n    private Address address;\n}\n\n@Getter\n@Setter\n@Valid\npublic static final class Address {\n\n  @NotEmpty\n  private String city;\n\n  @NotEmpty\n  private String state;\n}\n```\n\nRequest\n```curl\ncurl -X 'POST' \\\n  'http://localhost:8080/problems/handler-constraint-violation' \\\n  -H 'accept: */*' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"name\": \"a\",\n  \"designation\": \"aaaaaaaaaaaaaaaaa\",\n  \"address\": {\n    \"city\": \"string\"\n  }\n}'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#constraint-violations\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"Constraint violations has happened, please correct the request and try again\",\n  \"instance\": \"/problems/handler-constraint-violation\",\n  \"method\": \"POST\",\n  \"timestamp\": \"2023-10-29T16:41:59.876471+05:30\",\n  \"code\": \"constraint-violations\",\n  \"violations\": [\n    {\n      \"code\": \"400\",\n      \"detail\": \"User name length should be between 3 and 10\",\n      \"propertyPath\": \"name\"\n    },\n    {\n      \"code\": \"400\",\n      \"detail\": \"Address state name is required\",\n      \"propertyPath\": \"address.state\"\n    },\n    {\n      \"code\": \"400\",\n      \"detail\": \"User designation length should be between 2 and 5\",\n      \"propertyPath\": \"designation\"\n    }\n  ]\n}\n```\n\n#### PostgresDB Unique constraint violation error\n\nMake following request two time, 2nd time the exception will be thrown.\n\nRequest\n```curl\ncurl -X 'POST' \\\n  'http://localhost:8080/api/employees' \\\n  -H 'accept: */*' \\\n  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"name\": \"John Rambo\",\n  \"dob\": \"1983-06-06\"\n}'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#500\",\n  \"title\": \"Internal Server Error\",\n  \"status\": 500,\n  \"detail\": \"Employee name must be unique, a record with given name already exists\",\n  \"instance\": \"/api/employees\",\n  \"method\": \"POST\",\n  \"timestamp\": \"2023-10-29T16:44:10.917194+05:30\",\n  \"code\": \"500\"\n}\n```\n\n#### MongoDB Unique constraint violation error\n\nMake following request two time, 2nd time the exception will be thrown.\n\nRequest\n```curl\ncurl -X 'POST' \\\n  'http://localhost:8080/api/states' \\\n  -H 'accept: */*' \\\n  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"code\": \"HR\",\n  \"name\": \"Haryana\",\n  \"gstCode\": \"6\"\n}'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#500\",\n  \"title\": \"Internal Server Error\",\n  \"status\": 500,\n  \"detail\": \"State name must be unique\",\n  \"instance\": \"/api/states\",\n  \"method\": \"POST\",\n  \"timestamp\": \"2023-10-29T16:44:44.806613+05:30\",\n  \"code\": \"500\"\n}\n```\n\n#### Invalid Query parameters\n\nRequest\n```curl\ncurl -X 'GET' \\\n  'http://localhost:8080/problems/handler-invalid-query-strings?page=-1\u0026size=1' \\\n  -H 'accept: */*'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#constraint-violations\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"Constraint violations has happened, please correct the request and try again\",\n  \"instance\": \"/problems/handler-invalid-query-strings\",\n  \"method\": \"GET\",\n  \"timestamp\": \"2023-10-29T14:51:37.889537+05:30\",\n  \"code\": \"constraint-violations\",\n  \"violations\": [\n    {\n      \"code\": \"400\",\n      \"detail\": \"must be greater than or equal to 0\",\n      \"propertyPath\": \"page\"\n    }\n  ]\n}\n```\n\n#### Invalid format error\n\nRequest\n```curl\ncurl -X 'GET' \\\n  'http://localhost:8080/problems/handler-datetime-conversion?dateTime=2023-13-18T10%3A12%3A12Z' \\\n  -H 'accept: */*'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#400\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"Invalid date time value or format. Expected a valid date time in ISO format\",\n  \"instance\": \"/problems/handler-datetime-conversion\",\n  \"method\": \"GET\",\n  \"timestamp\": \"2023-10-29T16:05:09.953099+05:30\",\n  \"code\": \"400\",\n  \"propertyPath\": \"dateTime\"\n}\n```\n\n#### File upload max size exceeds error\n\nRequest\n```curl\ncurl -X 'POST' \\\n  'http://localhost:8080/problems/uploadfile' \\\n  -H 'accept: */*' \\\n  -H 'Content-Type: multipart/form-data' \\\n  -F 'file=@Large_File.pdf;type=application/pdf'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#400\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"Part exceeded the disk usage limit of 1024 bytes\",\n  \"instance\": \"/problems/uploadfile\",\n  \"method\": \"POST\",\n  \"timestamp\": \"2023-10-29T20:50:07.366581+05:30\",\n  \"code\": \"400\"\n}\n```\n\n### Spring framework thrown exceptions\n#### Invalid Media type error\n\nRequest\n```curl\ncurl -X 'POST' \\\n  'http://localhost:8080/problems/handler-json-body' \\\n  -H 'accept: */*' \\\n  -H 'Content-Type: application/xml' \\\n  -d '{\n  \"test\": \"string\"\n}'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#415\",\n  \"title\": \"Unsupported Media Type\",\n  \"status\": 415,\n  \"detail\": \"Media Type: application/xml Not Acceptable, Supported Media Types are: application/json\",\n  \"instance\": \"/problems/handler-json-body\",\n  \"method\": \"POST\",\n  \"timestamp\": \"2023-10-29T14:45:47.467268+05:30\",\n  \"code\": \"415\"\n}\n```\n\n#### Method not allowed error\n\nRequest\n```curl\ncurl -X 'POST' \\\n  'http://localhost:8080/problems/handler-datetime-conversion?dateTime=2023-04-18T10%3A12%3A12Z' \\\n  -H 'accept: */*'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#405\",\n  \"title\": \"Method Not Allowed\",\n  \"status\": 405,\n  \"detail\": \"Requested Method: POST not allowed, allowed methods are: GET\",\n  \"instance\": \"/problems/handler-datetime-conversion\",\n  \"method\": \"POST\",\n  \"timestamp\": \"2023-10-29T16:15:08.916369+05:30\",\n  \"code\": \"405\"\n}\n```\n\n### Programmatically thrown exceptions\n\n#### Any unhandled Throwable\n\nCode\n```java\nthrow new IllegalArgumentException(\"Expected argument invalid\", new IllegalStateException(\"Dummy cause\"));\n```\n\nRequest\n```curl\ncurl -X 'GET' \\\n  'http://localhost:8080/problems/handler-throwable' \\\n  -H 'accept: */*'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#500\",\n  \"title\": \"Internal Server Error\",\n  \"status\": 500,\n  \"detail\": \"Expected argument invalid\",\n  \"instance\": \"/problems/handler-throwable\",\n  \"method\": \"GET\",\n  \"timestamp\": \"2023-10-29T14:49:40.998497+05:30\",\n  \"code\": \"500\"\n}\n```\n\n#### Error with dynamic additional attributes\n\nCode\n```java\nProblem problem = Problems.newInstance(\"3456\", \"Bad Request\", \"Invalid request received, Please retry with correct input\")\n                .parameter(\"additional-attribute\", \"Some additional attribute\").build();\nthrow Problems.throwAble(HttpStatus.BAD_REQUEST, problem);\n```\n\nRequest\n```curl\ncurl -X 'GET' \\\n  'http://localhost:8080/problems/throw-problem-with-additional-attribute' \\\n  -H 'accept: */*'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#3456\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"Invalid request received, Please retry with correct input\",\n  \"instance\": \"/problems/throw-problem-with-additional-attribute\",\n  \"method\": \"GET\",\n  \"timestamp\": \"2023-10-29T16:24:37.976724+05:30\",\n  \"code\": \"3456\",\n  \"additional-attribute\": \"Some additional attribute\"\n}\n```\n\n#### Multiple errors\n\nCode\n```java\nApplicationException problemOne = Problems.newInstance(\"sample.problem.one\").throwAbleChecked();\nApplicationProblem problemTwo = Problems.newInstance(AppErrors.REMOTE_HOST_NOT_AVAILABLE).detailArgs(\"http://some.remote.host.com\").throwAble();\n\nMultiProblem problems = Problems.ofExceptions(HttpStatus.MULTI_STATUS, problemOne, problemTwo);\n\nProblem problemThree = Problems.newInstance(\"3456\", \"Bad Request\", \"Invalid request received, Please retry with correct input\")\n    .parameter(\"additional-attribute\", \"Some additional attribute\").build();\nproblems.add(problemThree);\nException exception = new IllegalStateException(\"Just for testing exception\");\nproblems.add(exception);\n\nProblem problem = Problems.newInstance(\"111\", \"Dummy\", \"Hardcode attributes broblem\").build();\nproblems.add(problem);\nthrow problems;\n```\n\nRequest\n```curl\ncurl -X 'GET' \\\n  'http://localhost:8080/problems/throw-multiple-problems' \\\n  -H 'accept: */*'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#207\",\n  \"title\": \"Multi-Status\",\n  \"status\": 207,\n  \"detail\": \"Multi-Status\",\n  \"instance\": \"/problems/throw-multiple-problems\",\n  \"method\": \"GET\",\n  \"timestamp\": \"2023-10-29T16:22:53.363785+05:30\",\n  \"code\": \"207\",\n  \"errors\": [\n    {\n      \"code\": \"500\",\n      \"title\": \"Internal Server Error\",\n      \"detail\": \"Sample error message defined in 'errors.properties'\"\n    },\n    {\n      \"code\": \"503\",\n      \"title\": \"Service Unavailable\",\n      \"detail\": \"Looks like something wrong with remote host: http://some.remote.host.com\"\n    },\n    {\n      \"code\": \"3456\",\n      \"title\": \"Bad Request\",\n      \"detail\": \"Invalid request received, Please retry with correct input\",\n      \"additional-attribute\": \"Some additional attribute\"\n    },\n    {\n      \"code\": \"500\",\n      \"title\": \"Internal Server Error\",\n      \"detail\": \"Just for testing exception\"\n    },\n    {\n      \"code\": \"111\",\n      \"title\": \"Dummy\",\n      \"detail\": \"Hardcode attributes broblem\"\n    }\n  ]\n}\n```\n\n### OpenAPI Specification violation error\n\nRequest\n```curl\ncurl -X 'POST' \\\n  'http://localhost:8080/api/pets' \\\n  -H 'accept: */*' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"id\": 0,\n  \"name\": \"string\",\n  \"category\": \"string\",\n  \"tags\": [\n    \"string\"\n  ],\n  \"status\": \"AVAILABLE\"\n}'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#constraint-violations\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"detail\": \"Constraint violations has happened, please correct the request and try again\",\n  \"instance\": \"/api/pets\",\n  \"method\": \"POST\",\n  \"timestamp\": \"2023-10-29T16:06:18.335463+05:30\",\n  \"code\": \"constraint-violations\",\n  \"violations\": [\n    {\n      \"code\": \"400\",\n      \"detail\": \"[Path '/id'] Numeric instance is lower than the required minimum (minimum: 1, found: 0)\"\n    }\n  ]\n}\n```\n\n### Security error\n\nRequest\n```curl\ncurl -X 'GET' \\\n  'http://localhost:8080/api/employees/1' \\\n  -H 'accept: */*'\n```\n\nResponse\n```json\n{\n  \"type\": \"http://localhost:8080/problems/help.html#401\",\n  \"title\": \"Unauthorized\",\n  \"status\": 401,\n  \"detail\": \"Either Authorization header bearer token is missing or invalid\",\n  \"instance\": \"/api/employees/1\",\n  \"method\": \"GET\",\n  \"timestamp\": \"2023-10-29T16:08:40.466566+05:30\",\n  \"code\": \"401\"\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofficiallysingh%2Fproblem-handler-webflux-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fofficiallysingh%2Fproblem-handler-webflux-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fofficiallysingh%2Fproblem-handler-webflux-demo/lists"}