Repository: quarkusio/quarkus
Issue: Error handling with @WithSpan (OpenTelemetry)

### Describe the bug

If an exception occurs in a method that's annotated with `@WithSpan`, the error won't be recorded in the trace.

### Expected behavior

Trace will contain error span.

### Actual behavior

Currently the error span is missing from the trace. Or in the reproducer's case the entire trace is missing.

### How to Reproduce?

Slightly modified `TracedResources` class from the OpenTelemetry quickstart. https://quarkus.io/guides/opentelemetry
```java
package org.acme.opentelemetry;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.jboss.logging.Logger;

@Path("/hello")
public class TracedResources {
    private static final Logger LOG = Logger.getLogger(TracedResources.class);

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(){
        LOG.info("hello");
        doSomething();
        return "hello";
    }

    @WithSpan
    public String doSomething() {
        throw new RuntimeException("foo");
    }
}
```
When the app is running, execute the command `curl http://localhost:8080/hello` and look at the trace result.

### Output of `uname -a` or `ver`

_No response_

### Output of `java -version`

openjdk version "17.0.5"

### GraalVM version (if different from Java)

_No response_

### Quarkus version or git rev

_No response_

### Build tool (ie. output of `mvnw --version` or `gradlew --version`)

_No response_

### Additional information

_No response_

Changed files:
extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/cdi/WithSpanInterceptor.java
extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/WithSpanInterceptorTest.java

diff --git a/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/WithSpanInterceptorTest.java b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/WithSpanInterceptorTest.java
index ee2a43b4721..52de43f905e 100644
--- a/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/WithSpanInterceptorTest.java
+++ b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/WithSpanInterceptorTest.java
@@ -3,9 +3,13 @@
 import static io.opentelemetry.api.trace.SpanKind.CLIENT;
 import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
 import static io.opentelemetry.api.trace.SpanKind.SERVER;
+import static io.opentelemetry.api.trace.StatusCode.ERROR;
 import static io.quarkus.opentelemetry.deployment.common.TestSpanExporter.getSpanByKindAndParentId;
 import static java.net.HttpURLConnection.HTTP_OK;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.util.List;
 
@@ -27,6 +31,7 @@
 import io.opentelemetry.instrumentation.annotations.SpanAttribute;
 import io.opentelemetry.instrumentation.annotations.WithSpan;
 import io.opentelemetry.sdk.trace.data.SpanData;
+import io.opentelemetry.sdk.trace.internal.data.ExceptionEventData;
 import io.quarkus.opentelemetry.deployment.common.TestSpanExporter;
 import io.quarkus.opentelemetry.deployment.common.TestSpanExporterProvider;
 import io.quarkus.runtime.StartupEvent;
@@ -62,6 +67,7 @@ void span() {
         List<SpanData> spanItems = spanExporter.getFinishedSpanItems(1);
         assertEquals("SpanBean.span", spanItems.get(0).getName());
         assertEquals(INTERNAL, spanItems.get(0).getKind());
+        assertNotEquals(ERROR, spanItems.get(0).getStatus().getStatusCode());
     }
 
     @Test
@@ -112,6 +118,25 @@ void spanCdiRest() {
         final SpanData server = getSpanByKindAndParentId(spans, SERVER, client.getSpanId());
     }
 
+    @Test
+    void spanWithException() {
+        try {
+            spanBean.spanWithException();
+            fail("Exception expected");
+        } catch (Exception e) {
+            assertThrows(RuntimeException.class, () -> {
+                throw e;
+            });
+        }
+        List<SpanData> spanItems = spanExporter.getFinishedSpanItems(1);
+        assertEquals("SpanBean.spanWithException", spanItems.get(0).getName());
+        assertEquals(INTERNAL, spanItems.get(0).getKind());
+        assertEquals(ERROR, spanItems.get(0).getStatus().getStatusCode());
+        assertEquals(1, spanItems.get(0).getEvents().size());
+        assertEquals("spanWithException for tests",
+                ((ExceptionEventData) spanItems.get(0).getEvents().get(0)).getException().getMessage());
+    }
+
     @ApplicationScoped
     public static class SpanBean {
         @WithSpan
@@ -119,6 +144,11 @@ public void span() {
 
         }
 
+        @WithSpan
+        public void spanWithException() {
+            throw new RuntimeException("spanWithException for tests");
+        }
+
         @WithSpan("name")
         public void spanName() {
 
diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/cdi/WithSpanInterceptor.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/cdi/WithSpanInterceptor.java
index 49eecfad212..2948f09f273 100644
--- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/cdi/WithSpanInterceptor.java
+++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/cdi/WithSpanInterceptor.java
@@ -70,6 +70,11 @@ public Object span(final ArcInvocationContext invocationContext) throws Exceptio
             }
 
             return result;
+        } catch (Throwable t) {
+            if (shouldStart) {
+                instrumenter.end(spanContext, methodRequest, null, t);
+            }
+            throw t;
         } finally {
             if (scope != null) {
                 scope.close();