question // "orElse" route
See original GitHub issueThe code I have until now in my application is the following (in Kotlin
, I hope it is still understandable).
getDispatcher(http)
.dispatch(Navigators.series(),
Bindings.on(HttpStatus.Series.SUCCESSFUL).call { response ->
deferred.resolve(Response(response, extract(response, clazz)))
},
Bindings.anySeries().dispatch(
Navigators.status(),
*errorBindings,
Bindings.anyStatus().call(ProblemRoute.problemHandling {
deferred.reject(it as Exception)
})
)
)
.join()
The problem I have here is that if the error that is returned is not of one of the content-type managed by ProblemRoute.problemHandling
, the complete call fails with a Riptide exception about no route being defined for this case.
I am looking for a way to add something after the use of problemHandling
that would semantically means: “If at this point, there was no route defined for this case, do <this>”.
For reference, here is the code for problemHandling
:
final Route route = Route.call(Exceptional.class, consumer);
return dispatch(contentType(),
on(PROBLEM).call(route),
on(X_DOT_PROBLEM).call(route),
on(X_DASH_PROBLEM).call(route));
The way I understand it, I would need to insert myself as a last parameter inside of that call to dispatch
(after on(X_DASH_PROBLEM.call(route)
).
To make my case work, I had to import some code from ProblemRoute
into my own application and do something like this:
// some static stuff
private val PROBLEM = parseMediaType("application/problem+json")
private val X_DOT_PROBLEM = parseMediaType("application/x.problem+json")
private val X_DASH_PROBLEM = parseMediaType("application/x-problem+json")
// and then, in my method
val problemJsonRoute = Route.call(Exceptional::class.java) {
deferred.reject(it as Exception)
}
val orElseConsumer: (ClientHttpResponse) -> Unit = {
deferred.reject(Exception(it.body.bufferedReader().readText()))
}
getDispatcher(http)
.dispatch(
Navigators.series(),
Bindings.on(SUCCESSFUL).call { response ->
deferred.resolve(Response(response, extract(response, clazz)))
},
Bindings.anySeries().call(RoutingTree.dispatch(
Navigators.status(),
*errorBindings,
Bindings.anyStatus().call(dispatch<MediaType>(
contentType(),
on<MediaType>(PROBLEM).call(problemJsonRoute),
on<MediaType>(X_DOT_PROBLEM).call(problemJsonRoute),
on<MediaType>(X_DASH_PROBLEM).call(problemJsonRoute),
Bindings.anyContentType().call(orElseConsumer)
))
))
)
.join()
It works and I could just go on like this, but I feel that is a shame to not use existing library code (ProblemRoute
).
Is there a “clean” way of doing what I want? I am quite new to Riptide and might not understand correctly the dispatching/routing system.
Thanks for any assistance you can provide!
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:5 (1 by maintainers)
Top GitHub Comments
I opened #206. @Adeynack Can you take a look if this would work for you?
@Adeynack Thanks for bringing this up!
I 100% agree. Providing a fallback like this totally makes sense.
Based on your code samples and observations I’d say you have an extremely good grasp of it.
@lukasniemeier-zalando
I already have a draft in the works.