Skip to content

Update Javadoc, versioning, and community standards for 1.5.0#37

Open
PasinduOG wants to merge 28 commits into
mainfrom
dev
Open

Update Javadoc, versioning, and community standards for 1.5.0#37
PasinduOG wants to merge 28 commits into
mainfrom
dev

Conversation

@PasinduOG
Copy link
Copy Markdown
Contributor

@PasinduOG PasinduOG commented May 8, 2026

This pull request introduces version 1.5.0 of the library, bringing a major new feature for exception handling and several documentation improvements. The highlight is the addition of a dynamic exception registry, enabling developers to map third-party or framework-specific exceptions to standardized HTTP responses without custom handler code. The documentation and build files are updated to reflect the new version and features, and a Contributor Covenant Code of Conduct is added to the repository.

Key changes:

New Features

  • Dynamic Exception Registry:
    Introduced ApiExceptionRegistry for centralized, thread-safe mapping of third-party exceptions (e.g., SQL, Security) to standard HTTP responses using a builder pattern. This allows external exceptions to be handled automatically by the global exception handler, reducing boilerplate and improving maintainability. [1] [2]

Documentation Updates

  • README enhancements:
    • Added documentation and usage examples for the new dynamic exception registry.
    • Updated installation instructions, version badges, and code snippets to reflect version 1.5.0.
    • Clarified that class-level security annotations (@AutoTrim, @XssCheck) were introduced in v1.3.0, not v1.4.0.
    • Improved package structure documentation and fixed minor typos. [1] [2] [3] [4] [5] [6] [7] [8]

Build and Versioning

  • Project version bump:
    • Updated pom.xml to version 1.5.0.
    • Updated Spring Boot dependency from 4.0.3 to 4.0.5.
    • Updated license URL to use HTTPS and set explicit compiler release property. [1] [2] [3]

Community and Governance

  • Code of Conduct:
    • Added CODE_OF_CONDUCT.md using Contributor Covenant 3.0 to establish clear community standards and enforcement guidelines.

Summary by CodeRabbit

  • New Features

    • Dynamic Exception Registry for mapping exceptions to HTTP status/messages; XSS validation support and dedicated XSS error handling.
    • Enhanced global response wrapping with configurable method/class message precedence.
  • Improvements

    • Improved error reporting with source-location and trace enrichment.
    • Strict string handling: opt-in trimming and XSS rejection for JSON inputs.
  • Documentation

    • README updated for v1.5.0-RC1; added CODE_OF_CONDUCT.
  • Dependencies

    • Spring Boot compatibility bumped to 4.0.5; test tooling updated.
  • Tests

    • New comprehensive tests for response wrapping, annotations, registry, and exception handling.

Review Change Stack

PasinduOG and others added 16 commits March 7, 2026 01:39
- Rewrote interface-level Javadoc with full usage example,
  error response format, and type parameter explanation
- Updated method-level Javadoc for getTargetException(),
  getStatus(), and getMessage() with detailed descriptions
- Added @Version, @SInCE, and cross-reference @see tags
- Bumped documented version to 1.4.0

Work in progress - not final release
feat(exception): update ApiExceptionTranslator Javadoc
…c exception mapping and pass any strings to AutoResponse annotation for showing custom messages
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@PasinduOG PasinduOG self-assigned this May 8, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a00ebb5-2bb7-413f-bb31-d280d08b956d

📥 Commits

Reviewing files that changed from the base of the PR and between d57b022 and 71a5648.

📒 Files selected for processing (26)
  • CODE_OF_CONDUCT.md
  • README.md
  • pom.xml
  • src/main/java/io/github/og4dev/advice/GlobalResponseWrapper.java
  • src/main/java/io/github/og4dev/advice/package-info.java
  • src/main/java/io/github/og4dev/annotation/AutoResponse.java
  • src/main/java/io/github/og4dev/annotation/AutoTrim.java
  • src/main/java/io/github/og4dev/annotation/XssCheck.java
  • src/main/java/io/github/og4dev/annotation/package-info.java
  • src/main/java/io/github/og4dev/config/ApiResponseAutoConfiguration.java
  • src/main/java/io/github/og4dev/config/package-info.java
  • src/main/java/io/github/og4dev/dto/ApiResponse.java
  • src/main/java/io/github/og4dev/dto/package-info.java
  • src/main/java/io/github/og4dev/exception/ApiException.java
  • src/main/java/io/github/og4dev/exception/ApiExceptionRegistry.java
  • src/main/java/io/github/og4dev/exception/GlobalExceptionHandler.java
  • src/main/java/io/github/og4dev/exception/XssValidationException.java
  • src/main/java/io/github/og4dev/exception/package-info.java
  • src/main/java/io/github/og4dev/filter/TraceIdFilter.java
  • src/main/java/io/github/og4dev/filter/package-info.java
  • src/main/java/io/github/og4dev/package-info.java
  • src/test/java/io/github/og4dev/advice/GlobalResponseWrapperTest.java
  • src/test/java/io/github/og4dev/annotation/AutoResponseAnnotationTest.java
  • src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java
  • src/test/java/io/github/og4dev/exception/ApiExceptionRegistryTest.java
  • src/test/java/io/github/og4dev/exception/GlobalExceptionHandlerTest.java
✅ Files skipped from review due to trivial changes (9)
  • src/main/java/io/github/og4dev/exception/ApiException.java
  • src/main/java/io/github/og4dev/dto/package-info.java
  • src/main/java/io/github/og4dev/config/package-info.java
  • src/main/java/io/github/og4dev/package-info.java
  • src/main/java/io/github/og4dev/annotation/XssCheck.java
  • src/main/java/io/github/og4dev/annotation/package-info.java
  • src/main/java/io/github/og4dev/advice/package-info.java
  • src/main/java/io/github/og4dev/exception/package-info.java
  • src/main/java/io/github/og4dev/annotation/AutoResponse.java
🚧 Files skipped from review as they are similar to previous changes (12)
  • src/main/java/io/github/og4dev/dto/ApiResponse.java
  • src/main/java/io/github/og4dev/annotation/AutoTrim.java
  • pom.xml
  • src/main/java/io/github/og4dev/filter/package-info.java
  • src/main/java/io/github/og4dev/filter/TraceIdFilter.java
  • src/test/java/io/github/og4dev/annotation/AutoResponseAnnotationTest.java
  • src/main/java/io/github/og4dev/exception/ApiExceptionRegistry.java
  • src/test/java/io/github/og4dev/advice/GlobalResponseWrapperTest.java
  • src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java
  • src/test/java/io/github/og4dev/exception/ApiExceptionRegistryTest.java
  • src/test/java/io/github/og4dev/exception/GlobalExceptionHandlerTest.java
  • src/main/java/io/github/og4dev/advice/GlobalResponseWrapper.java

📝 Walkthrough

Walkthrough

PR v1.5.0 introduces a new ApiExceptionRegistry for dynamic exception-to-response mapping, integrates it into GlobalExceptionHandler and auto-configuration, enhances GlobalResponseWrapper message selection from @AutoResponse annotations via method-first precedence, refactors the Jackson deserializer into a reusable class, and updates version metadata across all modules to 1.5.0 alongside comprehensive test coverage and documentation updates.

Changes

Code of Conduct & Governance

Layer / File(s) Summary
Community Standards
CODE_OF_CONDUCT.md
Contributor Covenant 3.0 code of conduct with community pledge, encouraged/restricted behaviors, reporting procedures, enforcement ladder, and scope.

Build & Infrastructure

Layer / File(s) Summary
Maven Configuration
pom.xml
Version bumped to 1.5.0-RC1; Spring Boot upgraded 4.0.3 → 4.0.5; added maven.compiler.release property (17); HTTPS license URL; added spring-boot-starter-test dependency and maven-surefire-plugin with dynamic agent loading.

Dynamic Exception Registry (New Feature)

Layer / File(s) Summary
Exception Registry API
src/main/java/io/github/og4dev/exception/ApiExceptionRegistry.java
Thread-safe insertion-ordered registry mapping exception types to ExceptionRule (status + message) with fluent register(), validation, and assignability-based getRule() polymorphic lookup.
Exception Handler Integration
src/main/java/io/github/og4dev/exception/GlobalExceptionHandler.java
Adds optional @Autowired(required = false) ApiExceptionRegistry constructor; adds getErrorLocation() helper extracting root-cause class/line; handleAllExceptions() now consults registry for custom status/message mappings with 500 fallback; enhanced logging with error location and traceId/timestamp enrichment.
Auto-Configuration Wiring
src/main/java/io/github/og4dev/config/ApiResponseAutoConfiguration.java
apiResponseAdvisor() now injects optional ApiExceptionRegistry into GlobalExceptionHandler. Jackson strictJsonCustomizer() refactored to use extracted AdvancedStringDeserializer static class for @AutoTrim and @XssCheck processing.

Response Wrapper & Annotation Enhancements

Layer / File(s) Summary
Response Wrapper Logic
src/main/java/io/github/og4dev/advice/GlobalResponseWrapper.java
Message selection now dynamically resolves from @AutoResponse (method-level first, class-level second, default "Success"); enhanced documentation for activation, excluded types, and string handling.
Annotation Documentation
src/main/java/io/github/og4dev/annotation/AutoResponse.java, AutoTrim.java, XssCheck.java
@AutoResponse docs expanded with Target Scopes and Custom Response Message sections. @AutoTrim and @XssCheck version updated and behavior clarified.

Documentation & Version Updates

Layer / File(s) Summary
README
README.md
Updated badges and installation examples for 1.5.0-RC1; added Dynamic Exception Registry feature highlight; updated project structure with dto/ package; added Dynamic Exception Registry configuration section; rewrote version history showing 1.5.0-RC1 as current release.
Package Documentation
src/main/java/io/github/og4dev/.../package-info.java (×7)
All package-level @version tags bumped 1.4.0 → 1.5.0-RC1 across advice, annotation, config, dto, exception, filter, and root packages; advice package-info expanded with registration and behavior documentation.

Test Coverage

Layer / File(s) Summary
Exception Registry Tests
src/test/java/io/github/og4dev/exception/ApiExceptionRegistryTest.java
Validates fluent registration, input validation (null/blank/empty rejection), rule storage, overwrite semantics, exact/polymorphic matching, parent-child precedence, and concurrent thread-safety.
Exception Handler Tests
src/test/java/io/github/og4dev/exception/GlobalExceptionHandlerTest.java
Validates constructor null-safety, registry-based exception mapping with polymorphic matching, first-match precedence, HTTP 500 fallback, trace-id MDC propagation, and handleApiException() registry independence.
Response Wrapper Tests
src/test/java/io/github/og4dev/advice/GlobalResponseWrapperTest.java
Validates supports() annotation detection and return-type exclusions; beforeBodyWrite() message resolution precedence (method > class > default); non-2xx status handling; null body wrapping; string payload JSON serialization; timestamp presence.
Annotation Tests
src/test/java/io/github/og4dev/annotation/AutoResponseAnnotationTest.java
Validates @AutoResponse runtime retention, targets (TYPE, METHOD), documentation marker, default message, class/method-level override, reflection detectability, and Unicode preservation.
Deserializer Tests
src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java
Validates default behavior (whitespace/HTML preserved), @AutoTrim field/class trimming with nulls, @XssCheck field/class XSS rejection, combined enforcement, and regex boundary cases.

Sequence Diagram

sequenceDiagram
  participant Client
  participant Handler as GlobalExceptionHandler
  participant Registry as ApiExceptionRegistry
  participant Res as HTTP_Response

  Client->>Handler: throws Exception
  Handler->>Handler: getErrorLocation(ex)
  Handler->>Registry: getRule(exceptionClass)
  alt registry has rule
    Registry-->>Handler: ExceptionRule(status,message)
    Handler->>Res: ProblemDetail(status,message)+traceId+timestamp
  else no rule
    Handler->>Res: ProblemDetail(500,"An unexpected error occurred")+traceId+timestamp
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

🐰 I hop through code with registry in paw,
Mapping errors so handlers won't thaw.
Annotations whisper messages true,
Tests nod and say, "This hop will do!"
v1.5.0-RC1 — a carrot for you.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Update Javadoc, versioning, and community standards for 1.5.0' accurately summarizes the main changes: comprehensive version bumping to 1.5.0, Javadoc updates across the codebase, and addition of community governance (CODE_OF_CONDUCT.md).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Note

Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/io/github/og4dev/advice/GlobalResponseWrapper.java (1)

146-153: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Set JSON content-type only after successful String serialization.

If serialization throws, the method returns the raw string fallback, but the response header may already be application/json, which can mislead clients.

Suggested fix
         if (body instanceof String) {
             try {
-                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                 assert apiResponse != null;
-                return objectMapper.writeValueAsString(apiResponse);
+                String serialized = objectMapper.writeValueAsString(apiResponse);
+                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+                return serialized;
             } catch (JacksonException e) {
                 return body;
             }
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/io/github/og4dev/advice/GlobalResponseWrapper.java` around
lines 146 - 153, In GlobalResponseWrapper, avoid setting the JSON content-type
before serialization; call objectMapper.writeValueAsString(apiResponse) first
and only if it succeeds set
response.getHeaders().setContentType(MediaType.APPLICATION_JSON) and return the
serialized String, and if objectMapper throws (catching JacksonException) return
the original body without modifying headers so the header change happens only on
successful serialization.
README.md (1)

166-184: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the corrupted character in the project structure tree.

The dto/ line contains mojibake (├─�� dto/), which breaks readability and copy/paste of the package tree.

Suggested fix
-├─�� dto/
+├── dto/
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 166 - 184, The project tree in README.md contains a
corrupted character on the dto entry ("├─�� dto/"); open the README.md and
replace that mojibake with the correct box-drawing segment used elsewhere (e.g.,
"├── dto/") so the line matches the other directory rows and restores
copy/paste/readability; update the entry that references ApiResponse.java (the
dto/ line) to use the proper characters and save the file.
🧹 Nitpick comments (2)
CODE_OF_CONDUCT.md (1)

51-51: 💤 Low value

Optional: Add hyphen to compound adjective.

When "mutually agreed upon" modifies a noun as a compound adjective, it should be hyphenated: "mutually agreed-upon resolution."

✏️ Proposed grammar fix
-Community Moderators take reports of violations seriously and will make every effort to respond in a timely manner. They will investigate all reports of code of conduct violations, reviewing messages, logs, and recordings, or interviewing witnesses and other participants. Community Moderators will keep investigation and enforcement actions as transparent as possible while prioritizing safety and confidentiality. In order to honor these values, enforcement actions are carried out in private with the involved parties, but communicating to the whole community may be part of a mutually agreed upon resolution.
+Community Moderators take reports of violations seriously and will make every effort to respond in a timely manner. They will investigate all reports of code of conduct violations, reviewing messages, logs, and recordings, or interviewing witnesses and other participants. Community Moderators will keep investigation and enforcement actions as transparent as possible while prioritizing safety and confidentiality. In order to honor these values, enforcement actions are carried out in private with the involved parties, but communicating to the whole community may be part of a mutually agreed-upon resolution.

As per coding guidelines, this suggestion comes from the static analysis hint regarding grammar conventions for compound adjectives.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CODE_OF_CONDUCT.md` at line 51, In the paragraph that ends with "mutually
agreed upon resolution", change the compound adjective to use a hyphen: replace
"mutually agreed upon resolution" with "mutually agreed-upon resolution" so the
phrase correctly hyphenates the compound modifier.
src/main/java/io/github/og4dev/config/ApiResponseAutoConfiguration.java (1)

97-99: ⚡ Quick win

Use ObjectProvider or Optional instead of @Autowired(required = false) for the optional registry parameter.

While @Autowired(required = false) on @Bean method parameters does work in Spring, the official Spring team guidance (GitHub issue #33710) explicitly recommends using ObjectProvider or Optional to model optional dependencies. ObjectProvider is the preferred approach for @Bean parameters as it provides clearer intent and better support for optional injection scenarios.

Suggested change
-    public GlobalExceptionHandler apiResponseAdvisor(`@Autowired`(required = false) ApiExceptionRegistry registry) {
-        return new GlobalExceptionHandler(registry);
+    public GlobalExceptionHandler apiResponseAdvisor(ObjectProvider<ApiExceptionRegistry> registryProvider) {
+        return new GlobalExceptionHandler(registryProvider.getIfAvailable());
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/io/github/og4dev/config/ApiResponseAutoConfiguration.java`
around lines 97 - 99, The apiResponseAdvisor `@Bean` method in
ApiResponseAutoConfiguration currently uses `@Autowired`(required = false) on the
ApiExceptionRegistry parameter; replace that with an
ObjectProvider<ApiExceptionRegistry> (preferred) or
Optional<ApiExceptionRegistry> parameter so the optional dependency is modeled
explicitly, then obtain the registry via provider.getIfAvailable() (or
optional.orElse(null)) and pass it into the GlobalExceptionHandler constructor
to preserve the existing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CODE_OF_CONDUCT.md`:
- Line 49: Complete the incomplete reporting sentence in CODE_OF_CONDUCT.md by
adding a clear verb and instruction; replace "To report a possible violation,
**pasinduogdev@gmail.com**" with a full sentence such as "To report a possible
violation, please email pasinduogdev@gmail.com" (or "please contact
pasinduogdev@gmail.com") so the action to take is explicit.
- Line 56: Remove the stray bold-marker artifact "****" from CODE_OF_CONDUCT.md
(the empty bold markers left in the document) so the file contains no empty
formatting; simply delete those four asterisks to eliminate the unintended bold
fragment and ensure surrounding markdown remains unchanged.

In `@src/main/java/io/github/og4dev/config/ApiResponseAutoConfiguration.java`:
- Around line 218-220: The thrown IllegalArgumentException in
ApiResponseAutoConfiguration (the XSS check: throw new
IllegalArgumentException(...)) causes
GlobalExceptionHandler.handleHttpMessageNotReadableException() to return a
generic malformed-JSON message and so violates the `@XssCheck` contract; fix this
by introducing a dedicated exception type (e.g., XssValidationException) and
throw that from the XSS check in ApiResponseAutoConfiguration, then update
GlobalExceptionHandler.handleHttpMessageNotReadableException() (or add a
specific `@ExceptionHandler` for XssValidationException) to return the documented
400 response with detail "Security Error: HTML tags or XSS payloads are not
allowed in the request." so the root-cause message in XssCheck.java is
preserved.

In `@src/main/java/io/github/og4dev/exception/GlobalExceptionHandler.java`:
- Around line 99-105: Add a no-arg constructor to GlobalExceptionHandler that
delegates to the existing constructor which accepts ApiExceptionRegistry so
existing callers/tests can still instantiate it; specifically, add a public
GlobalExceptionHandler() that calls the current constructor (the one with
parameter ApiExceptionRegistry) passing null (or Optional.empty) so behavior is
unchanged while preserving binary compatibility with direct instantiation.

---

Outside diff comments:
In `@README.md`:
- Around line 166-184: The project tree in README.md contains a corrupted
character on the dto entry ("├─�� dto/"); open the README.md and replace that
mojibake with the correct box-drawing segment used elsewhere (e.g., "├── dto/")
so the line matches the other directory rows and restores
copy/paste/readability; update the entry that references ApiResponse.java (the
dto/ line) to use the proper characters and save the file.

In `@src/main/java/io/github/og4dev/advice/GlobalResponseWrapper.java`:
- Around line 146-153: In GlobalResponseWrapper, avoid setting the JSON
content-type before serialization; call
objectMapper.writeValueAsString(apiResponse) first and only if it succeeds set
response.getHeaders().setContentType(MediaType.APPLICATION_JSON) and return the
serialized String, and if objectMapper throws (catching JacksonException) return
the original body without modifying headers so the header change happens only on
successful serialization.

---

Nitpick comments:
In `@CODE_OF_CONDUCT.md`:
- Line 51: In the paragraph that ends with "mutually agreed upon resolution",
change the compound adjective to use a hyphen: replace "mutually agreed upon
resolution" with "mutually agreed-upon resolution" so the phrase correctly
hyphenates the compound modifier.

In `@src/main/java/io/github/og4dev/config/ApiResponseAutoConfiguration.java`:
- Around line 97-99: The apiResponseAdvisor `@Bean` method in
ApiResponseAutoConfiguration currently uses `@Autowired`(required = false) on the
ApiExceptionRegistry parameter; replace that with an
ObjectProvider<ApiExceptionRegistry> (preferred) or
Optional<ApiExceptionRegistry> parameter so the optional dependency is modeled
explicitly, then obtain the registry via provider.getIfAvailable() (or
optional.orElse(null)) and pass it into the GlobalExceptionHandler constructor
to preserve the existing behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 085d68e0-3720-4e7e-aa57-8cb34d71aeaf

📥 Commits

Reviewing files that changed from the base of the PR and between 3d2ef8a and 770efee.

📒 Files selected for processing (20)
  • CODE_OF_CONDUCT.md
  • README.md
  • pom.xml
  • src/main/java/io/github/og4dev/advice/GlobalResponseWrapper.java
  • src/main/java/io/github/og4dev/advice/package-info.java
  • src/main/java/io/github/og4dev/annotation/AutoResponse.java
  • src/main/java/io/github/og4dev/annotation/AutoTrim.java
  • src/main/java/io/github/og4dev/annotation/XssCheck.java
  • src/main/java/io/github/og4dev/annotation/package-info.java
  • src/main/java/io/github/og4dev/config/ApiResponseAutoConfiguration.java
  • src/main/java/io/github/og4dev/config/package-info.java
  • src/main/java/io/github/og4dev/dto/ApiResponse.java
  • src/main/java/io/github/og4dev/dto/package-info.java
  • src/main/java/io/github/og4dev/exception/ApiException.java
  • src/main/java/io/github/og4dev/exception/ApiExceptionRegistry.java
  • src/main/java/io/github/og4dev/exception/GlobalExceptionHandler.java
  • src/main/java/io/github/og4dev/exception/package-info.java
  • src/main/java/io/github/og4dev/filter/TraceIdFilter.java
  • src/main/java/io/github/og4dev/filter/package-info.java
  • src/main/java/io/github/og4dev/package-info.java

Comment thread CODE_OF_CONDUCT.md Outdated
Comment thread CODE_OF_CONDUCT.md Outdated
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

✅ Created PR with unit tests: #38

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java (1)

138-138: ⚡ Quick win

Build JSON test payloads via Jackson APIs, not string concatenation.

Current JSON construction is brittle for escaped characters (quotes, backslashes) and can fail for parser reasons unrelated to the behavior under test.

Safer payload builder for tests
+ private String jsonValue(String field, String value) {
+     var node = objectMapper.createObjectNode();
+     if (value == null) {
+         node.putNull(field);
+     } else {
+         node.put(field, value);
+     }
+     return node.toString();
+ }

- String json = "{\"value\": \"" + maliciousPayload + "\"}";
+ String json = jsonValue("value", maliciousPayload);

Also applies to: 171-171, 197-197, 204-204, 242-242, 260-260, 271-271, 280-280, 289-289, 300-300

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java` at
line 138, The test constructs JSON payloads via string concatenation which
breaks on escaped characters; instead use Jackson to build and serialize the
payload: create an ObjectNode (or Map) and call
objectMapper.writeValueAsString(...) for a node with key "value" and the test
variable input, then use that resulting string for parsing; update all
occurrences that build json (the String json = "{\"value\": \"" + input + "\"}";
lines in AdvancedStringDeserializerTest, including the other occurrences at the
listed locations) to use ObjectMapper/ObjectNode.put("value", input) and
writeValueAsString to produce safe, escaped JSON.
src/test/java/io/github/og4dev/advice/GlobalResponseWrapperTest.java (1)

300-315: ⚡ Quick win

Strengthen the String-response test by asserting parsed JSON fields.

On line 311, the test comment claims "valid JSON," but the current substring-based assertions (contains()) can pass for malformed payloads. Parse the JSON and assert concrete field values instead.

Proposed test hardening
     `@Test`
     void beforeBodyWrite_returnsJsonString_whenBodyIsString() throws Exception {
         MethodParameter returnType = returnTypeOf(NoAnnotationController.class, "methodAnnotatedDefault");
         ServerHttpResponse response = mockResponse(200);

         Object result = wrapper.beforeBodyWrite(
                 "Hello World", returnType, MediaType.APPLICATION_JSON, null,
                 mock(ServerHttpRequest.class), response);

         assertThat(result).isInstanceOf(String.class);
         String jsonResult = (String) result;
-        // Should be a valid JSON string containing the ApiResponse structure
-        assertThat(jsonResult).contains("\"message\"");
-        assertThat(jsonResult).contains("\"status\"");
-        assertThat(jsonResult).contains("Hello World");
+        var json = objectMapper.readTree(jsonResult);
+        assertThat(json.get("message").asText()).isEqualTo("Success");
+        assertThat(json.get("status").asInt()).isEqualTo(HttpStatus.OK.value());
+        assertThat(json.get("content").asText()).isEqualTo("Hello World");
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/io/github/og4dev/advice/GlobalResponseWrapperTest.java` around
lines 300 - 315, Update the test
beforeBodyWrite_returnsJsonString_whenBodyIsString to parse the returned JSON
string and assert concrete fields rather than using contains(); call
wrapper.beforeBodyWrite with "Hello World" (as already done), cast the result to
String, parse it into a JSON object (e.g., via Jackson's ObjectMapper), and
assert that the parsed object's "message" equals "Hello World" and "status"
equals the expected ApiResponse status; locate this behavior around the test
method in GlobalResponseWrapperTest and reference the
returnTypeOf(NoAnnotationController.class, "methodAnnotatedDefault") and
wrapper.beforeBodyWrite invocation to implement the stronger assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java`:
- Around line 172-174: The test currently uses
assertThatThrownBy(...).isInstanceOf(Exception.class) which is too broad; update
each failing assertion in AdvancedStringDeserializerTest to expect the specific
exception thrown by the XSS rejection path (locate the assertions around
objectMapper.readValue(json, XssCheckFieldDto.class) and similar calls) —
replace Exception.class with the concrete exception your deserializer throws
(e.g., JsonMappingException or your custom XssValidationException) and also
assert the exception message or rootCause contains the XSS-specific indicator
(e.g., "XSS", "invalid input", or your validator message) so the test verifies
the correct failure mode rather than any Exception.

---

Nitpick comments:
In `@src/test/java/io/github/og4dev/advice/GlobalResponseWrapperTest.java`:
- Around line 300-315: Update the test
beforeBodyWrite_returnsJsonString_whenBodyIsString to parse the returned JSON
string and assert concrete fields rather than using contains(); call
wrapper.beforeBodyWrite with "Hello World" (as already done), cast the result to
String, parse it into a JSON object (e.g., via Jackson's ObjectMapper), and
assert that the parsed object's "message" equals "Hello World" and "status"
equals the expected ApiResponse status; locate this behavior around the test
method in GlobalResponseWrapperTest and reference the
returnTypeOf(NoAnnotationController.class, "methodAnnotatedDefault") and
wrapper.beforeBodyWrite invocation to implement the stronger assertions.

In `@src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java`:
- Line 138: The test constructs JSON payloads via string concatenation which
breaks on escaped characters; instead use Jackson to build and serialize the
payload: create an ObjectNode (or Map) and call
objectMapper.writeValueAsString(...) for a node with key "value" and the test
variable input, then use that resulting string for parsing; update all
occurrences that build json (the String json = "{\"value\": \"" + input + "\"}";
lines in AdvancedStringDeserializerTest, including the other occurrences at the
listed locations) to use ObjectMapper/ObjectNode.put("value", input) and
writeValueAsString to produce safe, escaped JSON.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8eeec5a3-9eb4-4192-a16b-7edb8b0ad508

📥 Commits

Reviewing files that changed from the base of the PR and between 770efee and d57b022.

📒 Files selected for processing (7)
  • pom.xml
  • src/main/java/io/github/og4dev/exception/GlobalExceptionHandler.java
  • src/test/java/io/github/og4dev/advice/GlobalResponseWrapperTest.java
  • src/test/java/io/github/og4dev/annotation/AutoResponseAnnotationTest.java
  • src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java
  • src/test/java/io/github/og4dev/exception/ApiExceptionRegistryTest.java
  • src/test/java/io/github/og4dev/exception/GlobalExceptionHandlerTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • pom.xml

Comment on lines +172 to +174
assertThatThrownBy(() -> objectMapper.readValue(json, XssCheckFieldDto.class))
.isInstanceOf(Exception.class);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use specific failure assertions instead of Exception.class.

Asserting Exception is too broad and can produce false positives from unrelated failures. Tighten these to the expected exception type/cause from XSS rejection.

Suggested tightening pattern
- assertThatThrownBy(() -> objectMapper.readValue(json, XssCheckFieldDto.class))
-         .isInstanceOf(Exception.class);
+ assertThatThrownBy(() -> objectMapper.readValue(json, XssCheckFieldDto.class))
+         .hasRootCauseInstanceOf(IllegalArgumentException.class);

Also applies to: 205-207, 243-245, 261-263, 281-283

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/io/github/og4dev/config/AdvancedStringDeserializerTest.java`
around lines 172 - 174, The test currently uses
assertThatThrownBy(...).isInstanceOf(Exception.class) which is too broad; update
each failing assertion in AdvancedStringDeserializerTest to expect the specific
exception thrown by the XSS rejection path (locate the assertions around
objectMapper.readValue(json, XssCheckFieldDto.class) and similar calls) —
replace Exception.class with the concrete exception your deserializer throws
(e.g., JsonMappingException or your custom XssValidationException) and also
assert the exception message or rootCause contains the XSS-specific indicator
(e.g., "XSS", "invalid input", or your validator message) so the test verifies
the correct failure mode rather than any Exception.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants