Open fabmars opened 4 years ago
PR on 1.3.x https://github.com/micronaut-projects/micronaut-core/pull/3729 But it should also be in 2.0.0 (master), awaiting feedback as of what to do there.
Note that this is most definitely not the way to add a type converter:
@Bean @Primary
public ConversionService conversionService(MyConverter myConverter) {
DefaultConversionService conversionService = new DefaultConversionService();
return conversionService.addConverter(String.class, Value.class, myConverter);
}
Create a bean that implements TypeConverterRegistrar
and use that to register the converter
Ah yeah I'm new to Micronaut (3 days and counting) and I must have missed the part in the documentation detailing that. Thanks for clarifying. I updated my code example at the top.
I want to be able to inject a given header into some controller argument (String) using MyAnnocation. But I also want to be able to give the
Value
type to that argument and convert theString
to thatValue
using ConversionService.To reproduce you need to wire some converters into your ConversionService, like so
And like so:
See the
context.reject(value, e)
? That's where the problem is.I used an annotation to tell Micronaut it has a request argument to process (like @Body for instance)
So far so good. Like I wrote earlier, for reasons specific to my project, I must be able to bind 2 different types (say: String and Value). Since the annotation-driven binders of the
RequestBinderRegistry
are stored in a map whose key is the actual annotation, I can only have 1 one-size-fits-allAnnotatedRequestArgumentBinder
and write something like:As you can see I'm using
context.with(argument)
to "force" the conversionService to do something in one of the 2 types I'm targeting. However, in THAT specific case,context.reject(Objecft value, Exception e)
on myValueConverter
will be "swallowed" into the void because the DefaultArgumentConversionContext instance created bycontext.with(argument)
does not override voidreject(Object value, Exception exception)
, hence it's NOT cascaded to the original context. In turnvoid reject(Exception exception)
is overridden and does cascade (but I'm losing the original value information in the process).Expected Behaviour
HTTP 400 "Failed to convert argument [value] for value [xxxxxxxx] due to: \<exception message>"
Actual Behaviour
In this specific case using
reject(Object value, Exception exception)
, the conversion isn't rejected and the value may be bound (to null if @Nullable) and the overall response's HTTP status isn't 400.Workaround
Use
void reject(Exception exception)
but the original value information is lost.Environment Information
Example Application
The fix being 3 lines, maybe we can skip this.
Fix
Trivial, add this
to
ConversionContext#with(Argument<T> argument)
This needs to be applied in 1.3.x and 2.0.x