Skip to content

Commit

Permalink
Reactive routes - handle RC.getBodyAsJson() returning null correctly
Browse files Browse the repository at this point in the history
- also share the failure callback class for all routes returning Uni
- resolves quarkusio#10858
  • Loading branch information
mkouba committed Jul 21, 2020
1 parent 06905ef commit 80db54d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,6 @@ private Methods() {
// Avoid direct instantiation
}

static void fail(BytecodeCreator creator, ResultHandle rc, ResultHandle exception) {
creator.invokeInterfaceMethod(FAIL, rc, exception);
}

static void returnAndClose(BytecodeCreator creator) {
creator.returnValue(null);
creator.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
import io.quarkus.vertx.web.runtime.RouteHandler;
import io.quarkus.vertx.web.runtime.RouteMatcher;
import io.quarkus.vertx.web.runtime.RoutingExchangeImpl;
import io.quarkus.vertx.web.runtime.UniFailureCallback;
import io.quarkus.vertx.web.runtime.VertxWebRecorder;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpMethod;
Expand Down Expand Up @@ -557,11 +558,11 @@ void implementInvoke(HandlerDescriptor descriptor, BeanInfo bean, MethodInfo met
// If the provided item is not null, and it's an object, the item is mapped to JSON and written into the response

FunctionCreator successCallback = getUniOnItemCallback(descriptor, invoke, routingContext, end, response);
FunctionCreator failureCallback = getUniOnFailureCallback(invoke, routingContext);
ResultHandle failureCallback = getUniOnFailureCallback(invoke, routingContext);

ResultHandle sub = invoke.invokeInterfaceMethod(Methods.UNI_SUBSCRIBE, res);
invoke.invokeVirtualMethod(Methods.UNI_SUBSCRIBE_WITH, sub, successCallback.getInstance(),
failureCallback.getInstance());
failureCallback);
} else if (descriptor.isReturningMulti()) {

// 3 cases - regular multi vs. sse multi vs. json array multi, we need to check the type.
Expand Down Expand Up @@ -756,23 +757,10 @@ private FunctionCreator getUniOnItemCallback(HandlerDescriptor descriptor, Metho
return callback;
}

/**
* Generates the following function:
*
* <pre>
* throwable -> rc.fail(throwable);
* </pre>
*
* @param writer the bytecode writer
* @param rc the reference to the RoutingContext variable
* @return the function creator.
*/
private FunctionCreator getUniOnFailureCallback(MethodCreator writer, ResultHandle rc) {
FunctionCreator callback = writer.createFunction(Consumer.class);
BytecodeCreator creator = callback.getBytecode();
Methods.fail(creator, rc, creator.getMethodParam(0));
Methods.returnAndClose(creator);
return callback;
private ResultHandle getUniOnFailureCallback(MethodCreator writer, ResultHandle routingContext) {
// new UniFailureCallback(ctx)
return writer.newInstance(MethodDescriptor.ofConstructor(UniFailureCallback.class, RoutingContext.class),
routingContext);
}

private ResultHandle getContentToWrite(HandlerDescriptor descriptor, ResultHandle response, ResultHandle res,
Expand Down Expand Up @@ -1119,9 +1107,17 @@ public ResultHandle get(MethodInfo method, Type paramType, Set<AnnotationInstanc
public ResultHandle get(MethodInfo method, Type paramType, Set<AnnotationInstance> annotations,
ResultHandle routingContext,
MethodCreator invoke, int position) {
return invoke.invokeVirtualMethod(Methods.JSON_OBJECT_MAP_TO,
invoke.invokeInterfaceMethod(Methods.GET_BODY_AS_JSON, routingContext),
invoke.loadClass(paramType.name().toString()));
AssignableResultHandle ret = invoke.createVariable(Object.class);
ResultHandle bodyAsJson = invoke.invokeInterfaceMethod(Methods.GET_BODY_AS_JSON,
routingContext);
BranchResult bodyIfNotNull = invoke.ifNotNull(bodyAsJson);
BytecodeCreator bodyNotNull = bodyIfNotNull.trueBranch();
bodyNotNull.assign(ret, bodyNotNull.invokeVirtualMethod(Methods.JSON_OBJECT_MAP_TO,
bodyAsJson,
invoke.loadClass(paramType.name().toString())));
BytecodeCreator bodyNull = bodyIfNotNull.falseBranch();
bodyNull.assign(ret, bodyNull.loadNull());
return ret;
}
}).build());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkus.vertx.web.runtime;

import java.util.function.Consumer;

import io.vertx.ext.web.RoutingContext;

public final class UniFailureCallback implements Consumer<Throwable> {

private final RoutingContext context;

public UniFailureCallback(RoutingContext context) {
this.context = context;
}

@Override
public void accept(Throwable t) {
context.fail(t);
}

}

0 comments on commit 80db54d

Please sign in to comment.