Skip to content

Commit 063cc9c

Browse files
Update docs for v2 and v3
1 parent 70295ea commit 063cc9c

8 files changed

Lines changed: 67 additions & 72 deletions

docs/02-problem4j-core.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ higher is required to use this library.
1313
<dependency>
1414
<groupId>io.github.problem4j</groupId>
1515
<artifactId>problem4j-core</artifactId>
16-
<version>1.4.3</version>
16+
<version>2.0.0</version>
1717
</dependency>
1818
</dependencies>
1919
```
2020
2. Gradle (Groovy or Kotlin DSL):
2121
```kt
2222
dependencies {
23-
implementation("io.github.problem4j:problem4j-core:1.4.3")
23+
implementation("io.github.problem4j:problem4j-core:2.0.0")
2424
}
2525
```
2626

@@ -116,8 +116,8 @@ throw new InterpolatedException("sub", "boom");
116116
```
117117

118118
After catching such exception, to be able to convert it to `Problem` object, you must have an instance of
119-
`ProblemMapper`. Problem4J Core provides a default implementation available from `ProblemMapper.create()` method, but
120-
you may use `AbstractProblemMapper` as a base to customize it further.
119+
`ProblemMapper`. Problem4J Core provides a default implementation - `DefaultProblemMapper`, but you may
120+
extend from it to customize it further.
121121

122122
Note that `ProblemMapper` returns a `ProblemBuilder` instance.
123123

@@ -127,7 +127,7 @@ import io.github.problem4j.core.ProblemMapper;
127127

128128
// ...
129129

130-
ProblemMapper problemMapper = ProblemMapper.create();
130+
ProblemMapper problemMapper = new DefaultProblemMapper();
131131
try {
132132
// ...
133133
} catch (InterpolatedException e) {
@@ -173,7 +173,7 @@ import io.github.problem4j.core.ProblemMapper;
173173
// ...
174174

175175
String traceId = someTracingFramework.getTraceId();
176-
ProblemMapper problemMapper = ProblemMapper.create();
176+
ProblemMapper problemMapper = new DefaultProblemMapper();
177177
try {
178178
// ...
179179
} catch (TracingAwareException e) {

docs/03-problem4j-jackson.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,26 +67,26 @@ not** declare `jackson-databind` as a transitive dependency.
6767
<dependency>
6868
<groupId>com.fasterxml.jackson.core</groupId>
6969
<artifactId>jackson-databind</artifactId>
70-
<version>2.20.1</version>
70+
<version>2.21.3</version>
7171
</dependency>
7272
<dependency>
7373
<groupId>io.github.problem4j</groupId>
7474
<artifactId>problem4j-core</artifactId>
75-
<version>1.4.3</version>
75+
<version>2.0.0</version>
7676
</dependency>
7777
<dependency>
7878
<groupId>io.github.problem4j</groupId>
7979
<artifactId>problem4j-jackson2</artifactId>
80-
<version>1.4.3</version>
80+
<version>2.0.0</version>
8181
</dependency>
8282
</dependencies>
8383
```
8484
2. Gradle (Kotlin DSL):
8585
```kt
8686
dependencies {
87-
implementation("com.fasterxml.jackson.core:jackson-databind:2.20.0")
88-
implementation("io.github.problem4j:problem4j-core:1.4.3")
89-
implementation("io.github.problem4j:problem4j-jackson2:1.4.3")
87+
implementation("com.fasterxml.jackson.core:jackson-databind:2.21.3")
88+
implementation("io.github.problem4j:problem4j-core:2.0.0")
89+
implementation("io.github.problem4j:problem4j-jackson2:2.0.0")
9090
}
9191
```
9292

@@ -150,26 +150,26 @@ not** declare `jackson-databind` as a transitive dependency.
150150
<dependency>
151151
<groupId>tools.jackson.core</groupId>
152152
<artifactId>jackson-databind</artifactId>
153-
<version>3.0.3</version>
153+
<version>3.1.2</version>
154154
</dependency>
155155
<dependency>
156156
<groupId>io.github.problem4j</groupId>
157157
<artifactId>problem4j-core</artifactId>
158-
<version>1.4.3</version>
158+
<version>2.0.0</version>
159159
</dependency>
160160
<dependency>
161161
<groupId>io.github.problem4j</groupId>
162162
<artifactId>problem4j-jackson3</artifactId>
163-
<version>1.4.3</version>
163+
<version>2.0.0</version>
164164
</dependency>
165165
</dependencies>
166166
```
167167
2. Gradle (Kotlin DSL):
168168
```kt
169169
dependencies {
170-
implementation("tools.jackson.core:jackson-databind:3.0.3")
171-
implementation("io.github.problem4j:problem4j-core:1.4.3")
172-
implementation("io.github.problem4j:problem4j-jackson3:1.4.3")
170+
implementation("tools.jackson.core:jackson-databind:3.1.2")
171+
implementation("io.github.problem4j:problem4j-core:2.0.0")
172+
implementation("io.github.problem4j:problem4j-jackson3:2.0.0")
173173
}
174174
```
175175

docs/04-problem4j-spring/01-setting-up-and-configuration.md

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@ Setting up dependencies and application properties.
1111
Add library as dependency to Maven or Gradle. See the actual versions on [Maven Central][maven-central]. Add it along
1212
with repository in your dependency manager. **Java 17** or higher is required to use this library.
1313

14-
Version `problem4j-spring-v1.x` is backwards compatible down to **Spring Boot `3.0.x`**, although it was tested mostly
15-
on versions between `3.2.x` and `3.5.x`. Integration with **Spring Boot 4** is released as `problem4j-spring-v2.x`.
16-
17-
| Spring Boot Version | Problem4J Spring Version |
18-
|---------------------|--------------------------|
19-
| `3.x` | `1.x` (latest - `1.2.9`) |
20-
| `4.x` | `2.x` (latest - `2.2.4`) |
14+
| Problem4J Spring Version | About |
15+
|--------------------------|-----------------------------------------|
16+
| `3.x` (latest - `3.0.0`) | Spring Boot `4.x`, `problem4j-core-2.x` |
17+
| `2.x` (latest - `2.2.4`) | Spring Boot `4.x`, `problem4j-core-1.x` |
18+
| `1.x` (latest - `1.2.9`) | Spring Boot `3.x`, `problem4j-core-1.x` |
2119

2220
Use version from the above table while managing your dependency or visit Maven Central to find out latest version in
2321
given generation.
@@ -66,8 +64,8 @@ errors generated by the library and those from your application.
6664
### `problem4j.tracing-header-name`
6765

6866
Property that specifies the name of the HTTP header used for tracing requests. If set, the trace identifier from this
69-
header is extracted and made available within the request context (`ProblemContext`). This value can be referenced in
70-
other configuration properties using the `{context.traceId}` placeholder. Defaults to `null` (disabled).
67+
header is extracted and stored in the request context (`ProblemContext`) under the `traceId` key. This value can be
68+
referenced in override templates using the `{context.traceId}` placeholder. Defaults to `null` (disabled).
7169

7270
See [Simple Tracing](./additional-features#simple-tracing) chapter for more info.
7371

@@ -78,6 +76,13 @@ identifiers to environment-specific URIs (for example, production vs. staging).
7876

7977
See [Problem Post-Processor](./problem-post-processor) chapter for more info.
8078

79+
### `problem4j.title-override`
80+
81+
Defines a template for overriding the `"title"` field of `Problem` responses. Useful for applying a consistent title
82+
format across all problems or injecting runtime context into the title. Defaults to `null` (disabled).
83+
84+
See [Problem Post-Processor](./problem-post-processor) chapter for more info.
85+
8186
### `problem4j.instance-override`
8287

8388
Defines a template for overriding the `"instance"` field of `Problem` responses. Useful for appending runtime context
@@ -93,14 +98,4 @@ stable set of exception / resolver types.
9398

9499
See [Resolver Caching](./additional-features#resolver-caching) chapter for more info.
95100

96-
### `problem4j.resolver-caching.max-cache-size`
97-
98-
Maximum number of resolver entries stored when caching is enabled. Defaults to `-1` (unbounded). Uses LRU (least
99-
recently used) eviction once the limit is exceeded. Values `<= 0` mean the cache is unbounded (no eviction).
100-
101-
**Note** that in most cases, there's no need to ever limit max cache size for problem resolvers, as the number of
102-
resolvers or exception types never increase at runtime.
103-
104-
See [Resolver Caching](./additional-features#resolver-caching) chapter for more info.
105-
106101
[maven-central]: https://central.sonatype.com/namespace/io.github.problem4j

docs/04-problem4j-spring/02-exception-handling.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public class ExampleExceptionResolver implements ProblemResolver {
115115
}
116116

117117
@Override
118-
public ProblemBuilder resolveBuilder(
118+
public Problem resolve(
119119
ProblemContext context, Exception ex, HttpHeaders headers, HttpStatusCode status) {
120120
ExampleException e = (ExampleException) ex;
121121
return Problem.builder()
@@ -125,7 +125,8 @@ public class ExampleExceptionResolver implements ProblemResolver {
125125
.detail("bad input for user " + e.getUserId())
126126
.instance("https://example.org/instances/" + context.getTraceId())
127127
.extension("userId", e.getUserId())
128-
.extension("fieldName", e.getFieldName());
128+
.extension("fieldName", e.getFieldName())
129+
.build();
129130
}
130131
}
131132
```
@@ -147,9 +148,6 @@ Will result in following response body:
147148
You can also override existing `ProblemResolver` implementations to extend models provided by this module. Build-in
148149
resolvers come with `@ConditionalOnMissingBean`, so they can be shadowed by custom ones in target applications.
149150

150-
`ProblemResolver` implementations return a `ProblemBuilder` for flexibility in constructing the final `Problem` object.
151-
It's a convenience method for further extending `Problem` object by processing downstream.
152-
153151
## Custom `@RestControllerAdvice`
154152

155153
While creating your own `@RestControllerAdvice`, make sure to position it with right `@Order`. In order for your custom

docs/04-problem4j-spring/06-problem-post-processor.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,44 @@ Final modification of `Problem` responses before HTTP response.
88

99
Problem4J provides a **post-processing mechanism** that allows modifying certain fields of a `Problem` object after it
1010
has been constructed. This feature makes it possible to generate environment-dependent or runtime-resolved URIs for
11-
fields such as `"type"` and `"instance"`, without embedding such logic into exception classes or resolvers.
11+
fields such as `"type"`, `"title"`, and `"instance"`, without embedding such logic into exception classes or resolvers.
1212

1313
Currently, the following fields can be overridden:
1414

1515
- `type` - the logical category of the problem
16+
- `title` - a short, human-readable summary of the problem
1617
- `instance` - an identifier of a specific occurrence, often a URI or trace reference
1718

1819
These overrides are applied by a **global post-processor** using templates defined in configuration properties.
1920
Templates for overriding problem fields may include placeholders that are dynamically replaced at runtime.
2021

21-
Available placeholders include:
22+
Available placeholders:
2223

2324
- for overriding `"type"` field:
2425
- `{problem.type}` - the original `"type"` value of the problem
25-
- for overriding "instance" field:
26+
- `{context.<key>}` - any value from the current request context (e.g. `{context.traceId}`)
27+
- for overriding `"title"` field:
28+
- `{problem.title}` - the original `"title"` value of the problem
29+
- `{context.<key>}` - any value from the current request context
30+
- for overriding `"instance"` field:
2631
- `{problem.instance}` - the original `"instance"` value of the problem
27-
- `{context.traceId}` - the trace identifier from the current request (if tracing is enabled)
32+
- `{context.<key>}` - any value from the current request context (e.g. `{context.traceId}`)
33+
34+
The `{context.<key>}` placeholder resolves values stored in `ProblemContext` for the current request. The built-in
35+
[Simple Tracing](./additional-features#simple-tracing) feature stores the trace identifier under the `traceId` key,
36+
making it available as `{context.traceId}`. You can also populate the context with custom keys by providing your own
37+
`ProblemContextFilter`.
2838

2939
General post-processing rules:
3040

3141
- Overrides are applied **only if all placeholders in the template can be resolved**:
3242
- `{problem.type}` - applied if the original `type` is **non-null**, **non-empty**, not `"about:blank"`.
43+
- `{problem.title}` - applied if the original `title` is **non-null** and **non-empty**.
3344
- `{problem.instance}` - applied if the original `instance` is **non-null** and **non-empty**.
34-
- `{context.traceId}` - applied if the context provides a **non-null**, **non-empty** trace ID.
45+
- `{context.<key>}` - applied if the context provides a **non-null**, **non-empty** value for that key.
3546
- If any referenced placeholder cannot be resolved, **the override is skipped** (occurrences of unknown placeholders
3647
also abort the override for that field).
37-
- The resulting values are **non-empty strings** and treated as valid URIs.
48+
- The resulting values are **non-empty strings** and treated as valid URIs (for `type` and `instance`).
3849
- If no override is set, fields remain as in the original `Problem`.
3950
- **Static templates** (no placeholders) are always applied, regardless of the original value.
4051

@@ -43,6 +54,7 @@ These rules ensure that field transformation is safe and predictable while allow
4354
Available configuration properties:
4455

4556
- [`problem4j.type-override`](./setting-up-and-configuration#problem4jtype-override)
57+
- [`problem4j.title-override`](./setting-up-and-configuration#problem4jtitle-override)
4658
- [`problem4j.instance-override`](./setting-up-and-configuration#problem4jinstance-override)
4759

4860
**Example:**

docs/04-problem4j-spring/07-additional-features.md

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,37 @@ sidebar_position: 7
44

55
# Additional Features
66

7-
Additional, incubating and/or experimental features of Problem4J Spring.
7+
Additional features of Problem4J Spring.
88

99
## Resolver Caching
1010

11-
| Feature Status | Info |
12-
|----------------|---------------------------------------------------------------------------|
13-
| **INCUBATING** | internal implementation might change, but public API should stay the same |
14-
1511
Resolving an exception involves finding the correct `ProblemResolver` by walking through the exception’s inheritance
1612
hierarchy - since resolvers can be defined generically for base exception types. This lookup process can involve
1713
reflection and multiple comparisons, which may introduce overhead when performed frequently (e.g., in high-throughput
1814
applications).
1915

2016
To improve performance, the resolver lookup results can be cached. Once an exception type has been resolved, the
2117
corresponding resolver is stored in a cache, allowing subsequent resolutions of the same type to be served instantly
22-
without re-evaluating the inheritance chain. Caching uses **LRU (least recently used)** eviction once the limit is
23-
exceeded, according to configuration.
18+
without re-evaluating the inheritance chain.
2419

2520
Available configuration properties:
2621

2722
- [`problem4j.resolver-caching.enabled`](./setting-up-and-configuration#problem4jresolver-cachingenabled)
28-
- [`problem4j.resolver-caching.max-cache-size`](./setting-up-and-configuration#problem4jresolver-cachingmax-cache-size)
2923

30-
The caching mechanism in `CachingProblemResolverStore` uses a `LinkedHashMap` wrapped with `synchronized` if eviction is
31-
enabled (`max-cache-size > 0`) or `ConcurrentHashMap` (`max-cache-size <= 0`) to avoid external dependencies. This is
32-
intentionally minimalistic and users can override it by supplying your own `ProblemResolverStore`implementation (or
33-
extending `AbstractProblemResolverStore`), backed by a proper caching provider and declaring it as `@Component` (all
34-
`@Bean`-s provided by this library are `@ConditionalOnMissingBean`).
24+
The caching mechanism in `CachingProblemResolverStore` uses a `ConcurrentHashMap` to avoid external dependencies. This
25+
is intentionally minimalistic and users can override it by supplying your own `ProblemResolverStore` implementation,
26+
backed by a proper caching provider and declaring it as `@Component` (all `@Bean`-s provided by this library are
27+
`@ConditionalOnMissingBean`).
3528

3629
**Example:**
3730

3831
```properties
3932
problem4j.resolver-caching.enabled=true
40-
problem4j.resolver-caching.max-cache-size=256
4133
```
4234

4335
Notes:
4436

45-
- As number of exceptions types do not increase at runtime, keeping default `max-cache-size = -1` (unbounded) is usually
46-
fine.
47-
- If you rarely introduce new resolver types, a small cache (64-256) is usually enough.
37+
- As the number of exception types does not increase at runtime, the cache is unbounded by design and safe to enable.
4838
- Leave disabled if startup / reflection cost is negligible or resolver set is highly dynamic.
4939

5040
## Simple Tracing

docs/05-tutorials/01-problem4j-and-spring-boot.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ The premier integration of Problem4J with Spring Boot.
1313
<dependency>
1414
<groupId>io.github.problem4j</groupId>
1515
<artifactId>problem4j-spring-webmvc</artifactId>
16-
<version>2.2.4</version>
16+
<version>3.0.0</version>
1717
</dependency>
1818
</dependencies>
1919
```
2020

2121
```kt
2222
dependencies {
23-
implementation("io.github.problem4j:problem4j-spring-webmvc:2.2.4")
23+
implementation("io.github.problem4j:problem4j-spring-webmvc:3.0.0")
2424
}
2525
```
2626

docs/05-tutorials/02-problem4j-and-javalin.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,20 @@ long as you can catch exceptions and convert them to `Problem` instances. This p
1717
<dependency>
1818
<groupId>io.github.problem4j</groupId>
1919
<artifactId>problem4j-core</artifactId>
20-
<version>1.4.3</version>
20+
<version>2.0.0</version>
2121
</dependency>
2222
<dependency>
2323
<groupId>io.github.problem4j</groupId>
2424
<artifactId>problem4j-jackson3</artifactId>
25-
<version>1.4.3</version>
25+
<version>2.0.0</version>
2626
</dependency>
2727
</dependencies>
2828
```
2929

3030
```kt
3131
dependencies {
32-
implementation("io.github.problem4j:problem4j-core:1.4.3")
33-
implementation("io.github.problem4j:problem4j-jackson3:1.4.3")
32+
implementation("io.github.problem4j:problem4j-core:2.0.0")
33+
implementation("io.github.problem4j:problem4j-jackson3:2.0.0")
3434
}
3535
```
3636

@@ -39,7 +39,7 @@ the compatible [Problem4J Jackson](../problem4j-jackson) module.
3939

4040
```java
4141
JsonMapper jsonMapper = JsonMapper.builder().findAndAddModules().build();
42-
ProblemMapper problemMapper = ProblemMapper.create();
42+
ProblemMapper problemMapper = new DefaultProblemMapper();
4343

4444
Javalin app = Javalin.create();
4545

0 commit comments

Comments
 (0)