Skip to content

Commit

Permalink
WebSockets Next: error handlers part 1
Browse files Browse the repository at this point in the history
- introduce OnError annotation
- add encoding/decoding exceptions
- also support global error handlers
- see quarkusio#39186

(cherry picked from commit bce9f55)
  • Loading branch information
mkouba authored and franz1981 committed May 20, 2024
1 parent 4b7bba9 commit 22fb0ae
Show file tree
Hide file tree
Showing 10 changed files with 695 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.quarkus.websockets.next.test.errors;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.net.URI;

import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;
import io.quarkus.websockets.next.BinaryDecodeException;
import io.quarkus.websockets.next.OnBinaryMessage;
import io.quarkus.websockets.next.OnError;
import io.quarkus.websockets.next.WebSocket;
import io.quarkus.websockets.next.WebSocketConnection;
import io.quarkus.websockets.next.test.utils.WSClient;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.mutiny.core.Context;

public class BinaryDecodeErrorTest {

@RegisterExtension
public static final QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot(root -> {
root.addClasses(Echo.class, WSClient.class);
});

@Inject
Vertx vertx;

@TestHTTPResource("echo")
URI testUri;

@Test
void testError() {
WSClient client = WSClient.create(vertx).connect(testUri);
client.send(Buffer.buffer("1"));
client.waitForMessages(1);
assertEquals("Problem decoding: 1", client.getLastMessage().toString());
}

@WebSocket(path = "/echo")
public static class Echo {

@OnBinaryMessage
void process(WebSocketConnection connection, Integer message) {
throw new IllegalStateException();
}

@OnError
String decodingError(BinaryDecodeException e) {
assertTrue(Context.isOnWorkerThread());
return "Problem decoding: " + e.getBytes().toString();
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.quarkus.websockets.next.test.errors;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.net.URI;

import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;
import io.quarkus.websockets.next.BinaryEncodeException;
import io.quarkus.websockets.next.OnBinaryMessage;
import io.quarkus.websockets.next.OnError;
import io.quarkus.websockets.next.WebSocket;
import io.quarkus.websockets.next.WebSocketConnection;
import io.quarkus.websockets.next.test.utils.WSClient;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.mutiny.core.Context;

public class BinaryEncodeErrorTest {

@RegisterExtension
public static final QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot(root -> {
root.addClasses(Echo.class, WSClient.class);
});

@Inject
Vertx vertx;

@TestHTTPResource("echo")
URI testUri;

@Test
void testError() {
WSClient client = WSClient.create(vertx).connect(testUri);
client.send(Buffer.buffer("1"));
client.waitForMessages(1);
assertEquals("Problem encoding: 1", client.getLastMessage().toString());
}

@WebSocket(path = "/echo")
public static class Echo {

@OnBinaryMessage
Integer process(WebSocketConnection connection, Buffer message) {
return Integer.parseInt(message.toString());
}

@OnError
String encodingError(BinaryEncodeException e) {
assertTrue(Context.isOnWorkerThread());
return "Problem encoding: " + e.getEncodedObject().toString();
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.quarkus.websockets.next.test.errors;

import static org.junit.jupiter.api.Assertions.fail;

import jakarta.enterprise.context.ApplicationScoped;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.websockets.next.OnError;
import io.quarkus.websockets.next.PathParam;
import io.quarkus.websockets.next.WebSocketServerException;

public class GlobalErrorHandlerWithPathParamTest {

@RegisterExtension
public static final QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot(root -> {
root.addClasses(GlobalErrorHandlers.class);
})
.setExpectedException(WebSocketServerException.class);

@Test
void testMultipleAmbiguousErrorHandlers() {
fail();
}

@ApplicationScoped
public static class GlobalErrorHandlers {

@OnError
void onError(IllegalStateException ise, @PathParam String illegal) {
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.quarkus.websockets.next.test.errors;

import static org.junit.jupiter.api.Assertions.fail;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.websockets.next.OnError;
import io.quarkus.websockets.next.OnOpen;
import io.quarkus.websockets.next.WebSocket;
import io.quarkus.websockets.next.WebSocketServerException;

public class MultipleAmbiguousErrorHandlersTest {

@RegisterExtension
public static final QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot(root -> {
root.addClasses(Endpoint.class);
})
.setExpectedException(WebSocketServerException.class);

@Test
void testMultipleAmbiguousErrorHandlers() {
fail();
}

@WebSocket(path = "/end")
public static class Endpoint {

@OnOpen
void open() {
}

@OnError
void onError1(IllegalStateException ise) {
}

@OnError
void onError2(IllegalStateException ise) {
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.quarkus.websockets.next.test.errors;

import static org.junit.jupiter.api.Assertions.fail;

import jakarta.enterprise.context.ApplicationScoped;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.websockets.next.OnError;
import io.quarkus.websockets.next.WebSocketServerException;

public class MultipleAmbiguousGlobalErrorHandlersTest {

@RegisterExtension
public static final QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot(root -> {
root.addClasses(GlobalErrorHandlers.class);
})
.setExpectedException(WebSocketServerException.class);

@Test
void testMultipleAmbiguousErrorHandlers() {
fail();
}

@ApplicationScoped
public static class GlobalErrorHandlers {

@OnError
void onError1(IllegalStateException ise) {
}

@OnError
void onError2(IllegalStateException ise) {
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.quarkus.websockets.next.test.errors;

import java.net.URI;
import java.time.Duration;

import jakarta.inject.Inject;

import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;
import io.quarkus.websockets.next.OnBinaryMessage;
import io.quarkus.websockets.next.OnError;
import io.quarkus.websockets.next.WebSocket;
import io.quarkus.websockets.next.WebSocketConnection;
import io.quarkus.websockets.next.test.utils.WSClient;
import io.smallrye.mutiny.Uni;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;

public class RuntimeErrorCloseConnectionTest {

@RegisterExtension
public static final QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot(root -> {
root.addClasses(Echo.class, WSClient.class);
});

@Inject
Vertx vertx;

@TestHTTPResource("echo")
URI testUri;

@Test
void testError() {
WSClient client = WSClient.create(vertx).connect(testUri);
client.sendAndAwait(Buffer.buffer("1"));
Awaitility.await().atMost(Duration.ofSeconds(5)).until(() -> client.isClosed());
}

@WebSocket(path = "/echo")
public static class Echo {

@OnBinaryMessage
void process(Buffer message) {
throw new IllegalStateException("Something went wrong");
}

@OnError
Uni<Void> runtimeProblem(RuntimeException e, WebSocketConnection connection) {
return connection.close();
}

}

}
Loading

0 comments on commit 22fb0ae

Please sign in to comment.