I'd like to strip the reactive DefaultErrorAttributes to only expose timestamp and message fields in the json response:
@Component
public class ReactiveHidingDefaultErrorAttributes extends org.springframework.boot.web.reactive.error.DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> map = super.getErrorAttributes(request, options);
map.keySet().retainAll(Set.of("timestamp", "message"));
return map;
}
}
@RestController
public class ExampleServlet {
@GetMapping("/test")
public Mono<String> greeting(ServerHttpRequest request) {
if(true) throw new RuntimeException("test");
}
}
Because especially the status field is redundant in the json rsp, as it is already send as http status code inside the response.
But if the status field is removed as written, the error handler will fail with NPE:
java.lang.NullPointerException: null
at org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler.getHttpStatus(DefaultErrorWebExceptionHandler.java:225) ~[spring-boot-autoconfigure-2.6.3.jar:2.6.3]
at org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler.renderErrorResponse(DefaultErrorWebExceptionHandler.java:147) ~[spring-boot-autoconfigure-2.6.3.jar:2.6.3]
at org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler.lambda$handle$0(AbstractErrorWebExceptionHandler.java:311) ~[spring-boot-autoconfigure-2.6.3.jar:2.6.3]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:125) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:201) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onSubscribe(FluxConcatArray.java:193) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onComplete(FluxConcatArray.java:258) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:78) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators.error(Operators.java:198) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onError(FluxDoOnEach.java:195) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onError(FluxContextWrite.java:121) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onError(FluxContextWrite.java:121) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators.error(Operators.java:198) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onError(MonoPeekTerminal.java:258) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onError(FluxContextWrite.java:121) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:270) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators.error(Operators.java:198) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:2063) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:270) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:2063) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:270) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:2063) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:270) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:2063) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:270) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators.error(Operators.java:198) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:2063) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:544) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onError(MonoPeekTerminal.java:258) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onError(MonoPeekTerminal.java:258) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators.error(Operators.java:198) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:270) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:142) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoZip$ZipCoordinator.signal(MonoZip.java:251) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoZip$ZipInner.onNext(MonoZip.java:336) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:139) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoZip$ZipInner.onSubscribe(MonoZip.java:325) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onSubscribe(MonoPeekTerminal.java:152) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:128) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:236) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onComplete(MonoFlatMap.java:181) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators.complete(Operators.java:137) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoZip.subscribe(MonoZip.java:120) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:255) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:282) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:863) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:139) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:169) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2068) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onSubscribe(MonoPeekTerminal.java:152) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:451) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:219) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:148) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:101) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:282) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:863) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:249) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:101) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:295) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:87) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoCurrentContext.subscribe(MonoCurrentContext.java:36) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:169) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:87) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:451) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:219) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:255) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2068) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Mono.subscribe(Mono.java:4400) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:82) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:846) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:608) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:588) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:465) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:294) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:230) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onComplete(FluxDefaultIfEmpty.java:109) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:269) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1817) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.signalCached(MonoCacheTime.java:337) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onNext(MonoCacheTime.java:354) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.publisher.MonoPublishOn$PublishOnSubscriber.run(MonoPublishOn.java:181) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) [reactor-core-3.4.14.jar:3.4.14]
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28) [reactor-core-3.4.14.jar:3.4.14]
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) [?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:829) [?:?]
By the way: as an alternative, I also tried changing the ErrorAttributeOptions, but which is only suitable to hide the exception and stacktrace fields, but not the others I also want to hide:
@Component
public class ReactiveHidingDefaultErrorAttributes extends org.springframework.boot.web.reactive.error.DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
return super.getErrorAttributes(request, ErrorAttributeOptions.of(Include.MESSAGE);
}
}
{
"timestamp": "2022-02-21T09:19:50.745+00:00",
"path": "/test",
"status": 500,
"error": "Internal Server Error",
"message": "test",
"requestId": "33e1262b"
}
Comment From: wilkinsona
Without an HttpStatus in the error attributes, we have no way of setting the status on the server response. What did you expect the response's status to be when you'd stripped out the status attribute and how did you expect it to be set?
Comment From: membersound
Well, I simply wanted to prevent duplicate information in the returned response. As the http response status code clear, there is no need to add the status once again into the json response. Therefore trying to exclude it.
Comment From: wilkinsona
At the moment, if you want to do that with WebFlux, you'll have to provide a custom ErrorWebExceptionHandler. Something like this, for example:
@Bean
@Order(-1)
ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes,
ServerProperties serverProperties, WebProperties webProperties, ObjectProvider<ViewResolver> viewResolvers,
ServerCodecConfigurer serverCodecConfigurer, ApplicationContext applicationContext) {
DefaultErrorWebExceptionHandler exceptionHandler = new DefaultErrorWebExceptionHandler(errorAttributes,
webProperties.getResources(), serverProperties.getError(), applicationContext) {
@Override
protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
Map<String, Object> error = getErrorAttributes(request,
getErrorAttributeOptions(request, MediaType.ALL));
int status = getHttpStatus(error);
error.remove("status");
return ServerResponse.status(status).contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(error));
}
};
exceptionHandler.setViewResolvers(viewResolvers.orderedStream().collect(Collectors.toList()));
exceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
exceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
return exceptionHandler;
}
FWIW, what you tried will work with a Servlet stack, but that approach is not without its problems as described in https://github.com/spring-projects/spring-boot/issues/20504.
I'll flag this for discussion at a team meeting to see if there's anything small that we want to do in 2.x to make this easier. More major changes will have to wait for 3.0.
Comment From: chengjk
your getErrorAttributes method removed status key in map . after this ,DefaultErrorWebExceptionHandler.java:225 try to get int status , then NPE.
update getErrorAttributes method, keep status key. it works.
Comment From: wilkinsona
@chengjk Thanks for trying to help, but the reporter of the issue already knows this. They are intentionally removing the status as they consider it to be redundant information.
Comment From: philwebb
I have a fix here, but it's quite a bit for a patch release and I'm starting to think it should be an enhancement in 3.4. Perhaps in 3.2 we should just protect against the NPE and use a status code of 500.
I'd like to see what the rest of the team think.
Comment From: wilkinsona
Those changes don't look too bad to me. I'm comfortable with them going in 3.2.x in their entirety.
Perhaps in 3.2 we should just protect against the NPE and use a status code of 500
I don't think we should do this as it would mean that the reactive stack has the same problem that #20504 is tracking for the servlet stack.