This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit d010001b6325bef3a1a3933299591686fd61c030
Author: Rene Cordier <[email protected]>
AuthorDate: Tue Apr 7 14:37:49 2026 +0700

    JAMES-4197 Add a SerializationResult interface for serialization results in 
EventSerializer
---
 .../org/apache/james/events/EventSerializer.java   | 13 ++--
 .../james/events/EventSerializersAggregator.java   | 15 ++--
 .../apache/james/events/SerializationResult.java   | 79 ++++++++++++++++++++++
 .../apache/james/events/EventBusTestFixture.java   | 18 ++---
 .../james/events/CassandraEventDeadLettersDAO.java |  2 +-
 .../org/apache/james/events/EventDispatcher.java   |  4 +-
 .../apache/james/events/GroupConsumerRetry.java    |  2 +-
 .../james/events/PostgresEventDeadLetters.java     |  2 +-
 .../james/event/json/MailboxEventSerializer.scala  | 36 ++++++++--
 .../james/event/json/AddedSerializationTest.java   |  6 +-
 .../event/json/ExpungedSerializationTest.java      |  6 +-
 .../event/json/FlagsUpdatedSerializationTest.java  |  6 +-
 .../MailboxACLUpdatedEventSerializationTest.java   |  2 +-
 .../event/json/MailboxAddedSerializationTest.java  |  2 +-
 .../json/MailboxDeletionSerializationTest.java     |  4 +-
 .../json/MailboxRenamedSerializationTest.java      |  2 +-
 .../MessageContentDeletionSerializationTest.java   |  6 +-
 .../json/MessageMoveEventSerializationTest.java    |  8 +--
 .../QuotaUsageUpdatedEventSerializationTest.java   |  2 +-
 .../james/jmap/change/JmapEventSerializer.scala    | 14 ++--
 .../webadmin/routes/EventDeadLettersRoutes.java    |  7 +-
 21 files changed, 173 insertions(+), 63 deletions(-)

diff --git 
a/event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java 
b/event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java
index 59b5d54a6a..462b2c2b82 100644
--- a/event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java
+++ b/event-bus/api/src/main/java/org/apache/james/events/EventSerializer.java
@@ -21,19 +21,18 @@ package org.apache.james.events;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
-import java.util.Optional;
 
 public interface EventSerializer {
-    Optional<String> toJson(Event event);
+    SerializationResult toJson(Event event);
 
-    Optional<String> toJson(Collection<Event> event);
+    SerializationResult toJson(Collection<Event> event);
 
-    default Optional<byte[]> toJsonBytes(Event event) {
-        return toJson(event).map(json -> 
json.getBytes(StandardCharsets.UTF_8));
+    default SerializationResult toJsonBytes(Event event) {
+        return toJson(event);
     }
 
-    default Optional<byte[]> toJsonBytes(Collection<Event> event) {
-        return toJson(event).map(json -> 
json.getBytes(StandardCharsets.UTF_8));
+    default SerializationResult toJsonBytes(Collection<Event> event) {
+        return toJson(event);
     }
 
     DeserializationResult asEvent(String serialized);
diff --git 
a/event-bus/api/src/main/java/org/apache/james/events/EventSerializersAggregator.java
 
b/event-bus/api/src/main/java/org/apache/james/events/EventSerializersAggregator.java
index f663567f16..e55bd93bf9 100644
--- 
a/event-bus/api/src/main/java/org/apache/james/events/EventSerializersAggregator.java
+++ 
b/event-bus/api/src/main/java/org/apache/james/events/EventSerializersAggregator.java
@@ -20,7 +20,6 @@
 package org.apache.james.events;
 
 import java.util.Collection;
-import java.util.Optional;
 import java.util.Set;
 
 import jakarta.inject.Inject;
@@ -36,11 +35,12 @@ public class EventSerializersAggregator implements 
EventSerializer {
     }
 
     @Override
-    public Optional<String> toJson(Event event) {
+    public SerializationResult toJson(Event event) {
         return allEventSerializers.stream()
             .map(eventSerializer -> eventSerializer.toJson(event))
-            .flatMap(Optional::stream)
-            .findFirst();
+            .filter(SerializationResult::isSuccess)
+            .findFirst()
+            .orElse(new SerializationResult.Failure("Could not serialize 
event: " + event));
     }
 
     @Override
@@ -53,11 +53,12 @@ public class EventSerializersAggregator implements 
EventSerializer {
     }
 
     @Override
-    public Optional<String> toJson(Collection<Event> events) {
+    public SerializationResult toJson(Collection<Event> events) {
         return allEventSerializers.stream()
             .map(eventSerializer -> eventSerializer.toJson(events))
-            .flatMap(Optional::stream)
-            .findFirst();
+            .filter(SerializationResult::isSuccess)
+            .findFirst()
+            .orElse(new SerializationResult.Failure("Could not serialize 
events: " + events));
     }
 
     @Override
diff --git 
a/event-bus/api/src/main/java/org/apache/james/events/SerializationResult.java 
b/event-bus/api/src/main/java/org/apache/james/events/SerializationResult.java
new file mode 100644
index 0000000000..e8d436f067
--- /dev/null
+++ 
b/event-bus/api/src/main/java/org/apache/james/events/SerializationResult.java
@@ -0,0 +1,79 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.events;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+
+public sealed interface SerializationResult permits 
SerializationResult.Success, SerializationResult.SuccessBytes, 
SerializationResult.Failure {
+    static SerializationResult of(Optional<String> maybeJson, String 
throwingMessage) {
+        return maybeJson.<SerializationResult>map(Success::new)
+            .orElse(new Failure(throwingMessage));
+    }
+
+    static SerializationResult ofBytes(Optional<byte[]> maybeJsonBytes, String 
throwingMessage) {
+        return 
maybeJsonBytes.<SerializationResult>map(SerializationResult.SuccessBytes::new)
+            .orElse(new SerializationResult.Failure(throwingMessage));
+    }
+
+    String json();
+
+    byte[] jsonBytes();
+
+    default boolean isSuccess() {
+        return this instanceof Success;
+    }
+
+    record Success(String json) implements SerializationResult {
+        @Override
+        public String json() {
+            return json;
+        }
+
+        @Override
+        public byte[] jsonBytes() {
+            return json.getBytes(StandardCharsets.UTF_8);
+        }
+    }
+
+    record SuccessBytes(byte[] jsonBytes) implements SerializationResult {
+        @Override
+        public String json() {
+            return new String(jsonBytes, StandardCharsets.UTF_8);
+        }
+
+        @Override
+        public byte[] jsonBytes() {
+            return jsonBytes;
+        }
+    }
+
+    record Failure(String throwingMessage) implements SerializationResult {
+        @Override
+        public String json() {
+            throw new RuntimeException(throwingMessage);
+        }
+
+        @Override
+        public byte[] jsonBytes() {
+            throw new RuntimeException(throwingMessage);
+        }
+    }
+}
diff --git 
a/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java 
b/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
index af0d419193..fcd8e25e5a 100644
--- 
a/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
+++ 
b/event-bus/api/src/test/java/org/apache/james/events/EventBusTestFixture.java
@@ -178,11 +178,11 @@ public interface EventBusTestFixture {
         static final String ARRAY_SEPARATOR = "^";
 
         @Override
-        public Optional<String> toJson(Event event) {
+        public SerializationResult toJson(Event event) {
             if (!(event instanceof TestEvent || event instanceof 
UnsupportedEvent)) {
-                return Optional.empty();
+                return new SerializationResult.Failure("Unknown event type: " 
+ event);
             }
-            return Optional.of(event.getClass().getCanonicalName() + "&" + 
event.getEventId().getId().toString() + "&" + event.getUsername().asString());
+            return new 
SerializationResult.Success(event.getClass().getCanonicalName() + "&" + 
event.getEventId().getId().toString() + "&" + event.getUsername().asString());
         }
 
         @Override
@@ -201,11 +201,13 @@ public interface EventBusTestFixture {
         }
 
         @Override
-        public Optional<String> toJson(Collection<Event> event) {
-            return Optional.of(event.stream()
-                .map(this::toJson)
-                .map(Optional::get)
-                .collect(Collectors.joining(ARRAY_SEPARATOR)));
+        public SerializationResult toJson(Collection<Event> event) {
+            return SerializationResult.of(
+                Optional.of(event.stream()
+                    .map(this::toJson)
+                    .map(SerializationResult::json)
+                    .collect(Collectors.joining(ARRAY_SEPARATOR))),
+                "Could not serialize events");
         }
 
         @Override
diff --git 
a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
 
b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
index 183a3a733e..7dcf3e4df5 100644
--- 
a/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
+++ 
b/event-bus/cassandra/src/main/java/org/apache/james/events/CassandraEventDeadLettersDAO.java
@@ -105,7 +105,7 @@ public class CassandraEventDeadLettersDAO {
 
     Mono<Void> store(Group group, Event failedEvent, 
EventDeadLetters.InsertionId insertionId) {
         String serializedEvent = eventSerializer.toJson(failedEvent)
-            .orElseThrow(() -> new RuntimeException("Could not serialize 
event: " + failedEvent));
+            .json();
 
         return executor.executeVoid(insertStatement.bind()
                 .setString(GROUP, group.asString())
diff --git 
a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
 
b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
index ef74ebce34..92864f705a 100644
--- 
a/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
+++ 
b/event-bus/distributed/src/main/java/org/apache/james/events/EventDispatcher.java
@@ -259,11 +259,11 @@ public class EventDispatcher {
 
     private byte[] serializeEvent(Event event) {
         return eventSerializer.toJsonBytes(event)
-            .orElseThrow(() -> new RuntimeException("Could not serialize 
event: " + event));
+            .jsonBytes();
     }
 
     private byte[] serializeEvents(Collection<Event> event) {
         return eventSerializer.toJsonBytes(event)
-            .orElseThrow(() -> new RuntimeException("Could not serialize 
events"));
+            .jsonBytes();
     }
 }
diff --git 
a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
 
b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
index 9b03c9171d..00d3c552cd 100644
--- 
a/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
+++ 
b/event-bus/distributed/src/main/java/org/apache/james/events/GroupConsumerRetry.java
@@ -101,7 +101,7 @@ class GroupConsumerRetry {
 
     private Mono<Void> sendRetryMessage(Event event, int currentRetryCount) {
         byte[] eventAsBytes = eventSerializer.toJsonBytes(event)
-            .orElseThrow(() -> new RuntimeException("Could not serialize 
event: " + event));
+            .jsonBytes();
 
         Mono<OutboundMessage> retryMessage = Mono.just(new OutboundMessage(
             retryExchangeName.asString(),
diff --git 
a/event-bus/postgres/src/main/java/org/apache/james/events/PostgresEventDeadLetters.java
 
b/event-bus/postgres/src/main/java/org/apache/james/events/PostgresEventDeadLetters.java
index 871b1f34e9..de967e62b9 100644
--- 
a/event-bus/postgres/src/main/java/org/apache/james/events/PostgresEventDeadLetters.java
+++ 
b/event-bus/postgres/src/main/java/org/apache/james/events/PostgresEventDeadLetters.java
@@ -51,7 +51,7 @@ public class PostgresEventDeadLetters implements 
EventDeadLetters {
         Preconditions.checkArgument(failDeliveredEvent != null, 
FAIL_DELIVERED_EVENT_CANNOT_BE_NULL);
 
         String serializedEvent = eventSerializer.toJson(failDeliveredEvent)
-            .orElseThrow(() -> new RuntimeException("Could not serialize 
event: " + failDeliveredEvent));
+            .json();
 
         InsertionId insertionId = InsertionId.random();
         return postgresExecutor.executeVoid(dslContext -> 
Mono.from(dslContext.insertInto(TABLE_NAME)
diff --git 
a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
 
b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
index 6a21ed08a9..72ff46bb6d 100644
--- 
a/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
+++ 
b/mailbox/event/json/src/main/scala/org/apache/james/event/json/MailboxEventSerializer.scala
@@ -21,7 +21,7 @@ package org.apache.james.event.json
 
 import java.time.Instant
 import java.util
-import java.util.{Optional, TreeMap => JavaTreeMap}
+import java.util.{TreeMap => JavaTreeMap}
 
 import jakarta.inject.Inject
 import julienrf.json.derived
@@ -30,7 +30,7 @@ import org.apache.james.core.quota.{QuotaCountLimit, 
QuotaCountUsage, QuotaSizeL
 import org.apache.james.event.json.DTOs.SystemFlag.SystemFlag
 import org.apache.james.event.json.DTOs._
 import org.apache.james.events.Event.EventId
-import org.apache.james.events.{DeserializationResult, EventSerializer, Event 
=> JavaEvent}
+import org.apache.james.events.{DeserializationResult, EventSerializer, 
SerializationResult, Event => JavaEvent}
 import org.apache.james.mailbox.MailboxSession.SessionId
 import org.apache.james.mailbox.events.MailboxEvents.Added.IS_APPENDED
 import org.apache.james.mailbox.events.MailboxEvents.{Added => JavaAdded, 
Expunged => JavaExpunged, FlagsUpdated => JavaFlagsUpdated, MailboxACLUpdated 
=> JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => 
JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, 
MailboxSubscribedEvent => JavaMailboxSubscribedEvent, MailboxUnsubscribedEvent 
=> JavaMailboxUnsubscribedEvent, MessageContentDeletionEvent => 
JavaMessageContentDeletionEvent, QuotaUsageUpdatedEvent =>  [...]
@@ -456,15 +456,39 @@ class JsonSerialize(mailboxIdFactory: MailboxId.Factory, 
messageIdFactory: Messa
 class MailboxEventSerializer @Inject()(mailboxIdFactory: MailboxId.Factory, 
messageIdFactory: MessageId.Factory, quotaRootDeserializer: 
QuotaRootDeserializer) extends EventSerializer {
   private val jsonSerialize = new JsonSerialize(mailboxIdFactory, 
messageIdFactory, quotaRootDeserializer)
 
-  override def toJson(event: JavaEvent): Optional[String] = 
Optional.of(jsonSerialize.toJson(event))
+  override def toJson(event: JavaEvent): SerializationResult =
+    try {
+      val serializedEvent: String = jsonSerialize.toJson(event)
+      new SerializationResult.Success(serializedEvent)
+    } catch {
+      case exception: Exception => new 
SerializationResult.Failure(exception.getMessage)
+    }
 
-  override def toJsonBytes(event: JavaEvent): Optional[Array[Byte]] = 
Optional.of(jsonSerialize.toJsonBytes(event))
+  override def toJsonBytes(event: JavaEvent): SerializationResult =
+    try {
+      val serializedBytesEvent: Array[Byte] = jsonSerialize.toJsonBytes(event)
+      new SerializationResult.SuccessBytes(serializedBytesEvent)
+    } catch {
+      case exception: Exception => new 
SerializationResult.Failure(exception.getMessage)
+    }
 
-  override def toJsonBytes(event: util.Collection[JavaEvent]): 
Optional[Array[Byte]] = Optional.of(jsonSerialize.toJsonBytes(event))
+  override def toJsonBytes(event: util.Collection[JavaEvent]): 
SerializationResult =
+    try {
+      val serializedBytesEvents: Array[Byte] = jsonSerialize.toJsonBytes(event)
+      new SerializationResult.SuccessBytes(serializedBytesEvents)
+    } catch {
+      case exception: Exception => new 
SerializationResult.Failure(exception.getMessage)
+    }
 
   def fromJson(json: String): JsResult[JavaEvent] = 
jsonSerialize.fromJson(json)
 
-  override def toJson(event: util.Collection[JavaEvent]): Optional[String] = 
Optional.of(jsonSerialize.toJson(event))
+  override def toJson(event: util.Collection[JavaEvent]): SerializationResult =
+    try {
+      val serializedEvents: String = jsonSerialize.toJson(event)
+      new SerializationResult.Success(serializedEvents)
+    } catch {
+      case exception: Exception => new 
SerializationResult.Failure(exception.getMessage)
+    }
 
   override def asEvents(serialized: String): DeserializationResult = {
     val result = jsonSerialize.fromJsonAsEvents(serialized)
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
index d5eb72a30a..3d5c63ffd5 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/AddedSerializationTest.java
@@ -172,13 +172,13 @@ class AddedSerializationTest {
 
     @Test
     void addedShouldBeWellSerialized() {
-        assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_ADDED_EVENT).get())
+        assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_ADDED_EVENT).json())
             .isEqualTo(DEFAULT_ADDED_EVENT_JSON);
     }
 
     @Test
     void addedWithDistinctMessageIdAndThreadIdShouldBeWellSerialized() {
-        
assertThatJson(EVENT_SERIALIZER.toJson(ADDED_WITH_DISTINCT_MESSAGE_ID_AND_THREAD_ID_EVENT).get())
+        
assertThatJson(EVENT_SERIALIZER.toJson(ADDED_WITH_DISTINCT_MESSAGE_ID_AND_THREAD_ID_EVENT).json())
             
.isEqualTo(ADDED_WITH_DISTINCT_MESSAGE_ID_AND_THREAD_ID_EVENT_JSON);
     }
 
@@ -252,7 +252,7 @@ class AddedSerializationTest {
 
         @Test
         void addedShouldBeWellSerializedWhenMapKeyIsEmpty() {
-            assertThatJson(EVENT_SERIALIZER.toJson(emptyAddedEvent).get())
+            assertThatJson(EVENT_SERIALIZER.toJson(emptyAddedEvent).json())
                 .isEqualTo(emptyAddedEventJson);
         }
 
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
index e9f4550322..be145e6bfd 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/ExpungedSerializationTest.java
@@ -166,13 +166,13 @@ class ExpungedSerializationTest {
 
     @Test
     void expungedShouldBeWellSerialized() {
-        assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_EXPUNGED_EVENT).get())
+        assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_EXPUNGED_EVENT).json())
             .isEqualTo(DEFAULT_EXPUNGED_EVENT_JSON);
     }
 
     @Test
     void expungedWithDistinctMessageIdAndThreadIdShouldBeWellSerialized() {
-        
assertThatJson(EVENT_SERIALIZER.toJson(EXPUNGED_WITH_DISTINCT_MESSAGE_ID_AND_THREAD_ID_EVENT).get())
+        
assertThatJson(EVENT_SERIALIZER.toJson(EXPUNGED_WITH_DISTINCT_MESSAGE_ID_AND_THREAD_ID_EVENT).json())
             
.isEqualTo(EXPUNGED_WITH_DISTINCT_MESSAGE_ID_AND_THREAD_ID_EVENT_JSON);
     }
 
@@ -242,7 +242,7 @@ class ExpungedSerializationTest {
 
         @Test
         void expungedShouldBeWellSerializedWhenMapKeyIsEmpty() {
-            assertThatJson(EVENT_SERIALIZER.toJson(emptyExpungedEvent).get())
+            assertThatJson(EVENT_SERIALIZER.toJson(emptyExpungedEvent).json())
                 .isEqualTo(emptyExpungedEventJson);
         }
 
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
index 3ffa626bf5..d6d579b533 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/FlagsUpdatedSerializationTest.java
@@ -129,7 +129,7 @@ class FlagsUpdatedSerializationTest {
 
     @Test
     void flagsUpdatedShouldBeWellSerialized() {
-        assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_EVENT).get())
+        assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_EVENT).json())
             .when(Option.IGNORING_ARRAY_ORDER)
             .isEqualTo(DEFAULT_EVENT_JSON);
     }
@@ -164,7 +164,7 @@ class FlagsUpdatedSerializationTest {
 
         @Test
         void flagsUpdatedShouldBeWellSerialized() {
-            
assertThatJson(EVENT_SERIALIZER.toJson(emptyUpdatedFlagsEvent).get())
+            
assertThatJson(EVENT_SERIALIZER.toJson(emptyUpdatedFlagsEvent).json())
                 .when(Option.IGNORING_ARRAY_ORDER)
                 .isEqualTo(EVENT_JSON_WITH_EMPTY_UPDATED_FLAGS);
         }
@@ -272,7 +272,7 @@ class FlagsUpdatedSerializationTest {
 
         @Test
         void flagsUpdatedShouldBeWellSerialized() {
-            assertThatJson(EVENT_SERIALIZER.toJson(eventWithMessageIds).get())
+            assertThatJson(EVENT_SERIALIZER.toJson(eventWithMessageIds).json())
                 .when(Option.IGNORING_ARRAY_ORDER)
                 .isEqualTo(EVENT_WITH_MESSAGE_IDS_JSON);
         }
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
index 405a596f1f..479d13844b 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
@@ -75,7 +75,7 @@ class MailboxACLUpdatedEventSerializationTest {
 
     @Test
     void mailboxACLUpdatedShouldBeSerialized() {
-        assertThatJson(EVENT_SERIALIZER.toJson(MAILBOX_ACL_UPDATED).get())
+        assertThatJson(EVENT_SERIALIZER.toJson(MAILBOX_ACL_UPDATED).json())
             .isEqualTo(MAILBOX_ACL_UPDATED_JSON);
     }
 
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
index d80f32b19f..18ad97db27 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxAddedSerializationTest.java
@@ -60,7 +60,7 @@ class MailboxAddedSerializationTest {
 
     @Test
     void mailboxAddedShouldBeWellSerialized() {
-        assertThatJson(EVENT_SERIALIZER.toJson(EVENT_1).get())
+        assertThatJson(EVENT_SERIALIZER.toJson(EVENT_1).json())
             .isEqualTo(JSON_1);
     }
 
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
index 264959a83c..a40e14aa7d 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxDeletionSerializationTest.java
@@ -139,7 +139,7 @@ class MailboxDeletionSerializationTest {
 
     @Test
     void mailboxDeletionShouldBeWellSerialized() {
-        
assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_MAILBOX_DELETION_EVENT).get())
+        
assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_MAILBOX_DELETION_EVENT).json())
             .isEqualTo(DEFAULT_EVENT_JSON);
     }
 
@@ -151,7 +151,7 @@ class MailboxDeletionSerializationTest {
 
     @Test
     void mailboxDeletionWithEmptyACLShouldBeWellSerialized() {
-        
assertThatJson(EVENT_SERIALIZER.toJson(EMPTY_ACL_MAILBOX_DELETION_EVENT).get())
+        
assertThatJson(EVENT_SERIALIZER.toJson(EMPTY_ACL_MAILBOX_DELETION_EVENT).json())
             .isEqualTo(EVENT_WITH_EMPTY_ACL_JSON);
     }
 
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
index 9158755962..f0b96d2568 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxRenamedSerializationTest.java
@@ -76,7 +76,7 @@ class MailboxRenamedSerializationTest {
 
     @Test
     void mailboxRenamedShouldBeWellSerialized() {
-        
assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_MAILBOX_RENAMED_EVENT).get())
+        
assertThatJson(EVENT_SERIALIZER.toJson(DEFAULT_MAILBOX_RENAMED_EVENT).json())
             .isEqualTo(DEFAULT_MAILBOX_RENAMED_EVENT_JSON);
     }
 
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java
index 23749b7760..61b8d879f4 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageContentDeletionSerializationTest.java
@@ -234,8 +234,8 @@ class MessageContentDeletionSerializationTest {
 
     @Test
     void messageContentDeletionEventShouldBeWellSerialized() {
-        assertThatJson(EVENT_SERIALIZER.toJson(EVENT).get()).isEqualTo(JSON);
-        
assertThatJson(EVENT_SERIALIZER.toJson(EVENT_WITHOUT_HEADER_CONTENT).get()).isEqualTo(JSON_WITHOUT_HEADER_CONTENT);
+        assertThatJson(EVENT_SERIALIZER.toJson(EVENT).json()).isEqualTo(JSON);
+        
assertThatJson(EVENT_SERIALIZER.toJson(EVENT_WITHOUT_HEADER_CONTENT).json()).isEqualTo(JSON_WITHOUT_HEADER_CONTENT);
     }
 
     @Test
@@ -246,7 +246,7 @@ class MessageContentDeletionSerializationTest {
 
     @Test
     void messageContentDeletionEventWithMailboxPathShouldBeWellSerialized() {
-        
assertThatJson(EVENT_SERIALIZER.toJson(EVENT_WITH_MAILBOX_PATH).get()).isEqualTo(JSON_WITH_MAILBOX_PATH);
+        
assertThatJson(EVENT_SERIALIZER.toJson(EVENT_WITH_MAILBOX_PATH).json()).isEqualTo(JSON_WITH_MAILBOX_PATH);
     }
 
     @Test
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
index 9e2067a75f..e2661cdecc 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/MessageMoveEventSerializationTest.java
@@ -59,7 +59,7 @@ class MessageMoveEventSerializationTest {
 
     @Test
     void messageMoveEventShouldBeWellSerialized() {
-        assertThatJson(EVENT_SERIALIZER.toJson(EVENT).get())
+        assertThatJson(EVENT_SERIALIZER.toJson(EVENT).json())
             .isEqualTo(JSON);
     }
 
@@ -94,7 +94,7 @@ class MessageMoveEventSerializationTest {
 
             @Test
             void messageMoveEventShouldBeWellSerialized() {
-                assertThatJson(EVENT_SERIALIZER.toJson(event).get())
+                assertThatJson(EVENT_SERIALIZER.toJson(event).json())
                     .isEqualTo(json);
             }
 
@@ -128,7 +128,7 @@ class MessageMoveEventSerializationTest {
 
             @Test
             void messageMoveEventShouldBeWellSerialized() {
-                assertThatJson(EVENT_SERIALIZER.toJson(event).get())
+                assertThatJson(EVENT_SERIALIZER.toJson(event).json())
                     .isEqualTo(json);
             }
 
@@ -162,7 +162,7 @@ class MessageMoveEventSerializationTest {
 
             @Test
             void messageMoveEventShouldBeWellSerialized() {
-                assertThatJson(EVENT_SERIALIZER.toJson(event).get())
+                assertThatJson(EVENT_SERIALIZER.toJson(event).json())
                     .isEqualTo(json);
             }
 
diff --git 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
index f1703a787e..79f42c2560 100644
--- 
a/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
+++ 
b/mailbox/event/json/src/test/java/org/apache/james/event/json/QuotaUsageUpdatedEventSerializationTest.java
@@ -77,7 +77,7 @@ class QuotaUsageUpdatedEventSerializationTest {
 
     @Test
     void toJsonShouldReturnQuotaEventJson() {
-        
assertThatJson(EVENT_SERIALIZER.toJson(eventWithUserContainsUsername).get())
+        
assertThatJson(EVENT_SERIALIZER.toJson(eventWithUserContainsUsername).json())
             .isEqualTo(quotaUsageUpdatedEvent);
     }
 
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/JmapEventSerializer.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/JmapEventSerializer.scala
index 65eb6c33e9..85217a574c 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/JmapEventSerializer.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/JmapEventSerializer.scala
@@ -26,7 +26,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
 import jakarta.inject.Inject
 import org.apache.james.core.Username
 import org.apache.james.events.Event.EventId
-import org.apache.james.events.{DeserializationResult, Event, EventSerializer}
+import org.apache.james.events.{DeserializationResult, Event, EventSerializer, 
SerializationResult}
 import org.apache.james.jmap.api.change.TypeStateFactory
 import org.apache.james.jmap.api.model.{State, TypeName}
 import org.apache.james.jmap.core.UuidState
@@ -84,21 +84,25 @@ case class JmapEventSerializer 
@Inject()(stateChangeEventDTOFactory: StateChange
     
.forModules(stateChangeEventDTOFactory.dtoModule.asInstanceOf[EventDTOModule[Event,
 EventDTO]])
     .withoutNestedType()
 
-  override def toJson(event: Event): Optional[String] = 
genericSerializer.maybeSerialize(event)
+  override def toJson(event: Event): SerializationResult = 
SerializationResult.of(
+    genericSerializer.maybeSerialize(event),
+    "Could not serialize event " + event)
 
   override def asEvent(serialized: String): DeserializationResult = 
DeserializationResult.of(
     genericSerializer.maybeDeserialize(serialized),
     "Could not deserialize event " + serialized)
 
-  override def toJsonBytes(event: Event): Optional[Array[Byte]] = 
genericSerializer.maybeSerializeToBytes(event)
+  override def toJsonBytes(event: Event): SerializationResult = 
SerializationResult.ofBytes(
+    genericSerializer.maybeSerializeToBytes(event),
+    "Could not serialize event " + event)
 
   override def fromBytes(serialized: Array[Byte]): DeserializationResult = 
DeserializationResult.of(
     genericSerializer.maybeDeserializeFromBytes(serialized),
     "Could not deserialize event " + serialized.map(_.toChar).mkString)
 
-  override def toJson(event: util.Collection[Event]): Optional[String] = {
+  override def toJson(event: util.Collection[Event]): SerializationResult = {
     if (event.size() != 1) {
-      Optional.empty()
+      new SerializationResult.Failure("Not supported for multiple events, 
please serialize separately")
     }
     toJson(event.iterator().next())
   }
diff --git 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java
 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java
index 74a7751ca4..3809171135 100644
--- 
a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java
+++ 
b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/EventDeadLettersRoutes.java
@@ -26,6 +26,7 @@ import jakarta.inject.Inject;
 import org.apache.james.events.EventDeadLetters;
 import org.apache.james.events.EventSerializer;
 import org.apache.james.events.Group;
+import org.apache.james.events.SerializationResult;
 import org.apache.james.task.TaskManager;
 import org.apache.james.util.streams.Limit;
 import org.apache.james.webadmin.Routes;
@@ -106,9 +107,9 @@ public class EventDeadLettersRoutes implements Routes {
         EventDeadLetters.InsertionId insertionId = parseInsertionId(request);
 
         return eventDeadLettersService.getEvent(group, insertionId)
-            .flatMap(event -> eventSerializer.toJson(event)
-                .map(Mono::just)
-                .orElseGet(Mono::empty))
+            .map(eventSerializer::toJson)
+            .filter(SerializationResult::isSuccess)
+            .map(SerializationResult::json)
             .switchIfEmpty(Mono.fromRunnable(() -> 
response.status(HttpStatus.NOT_FOUND_404)))
             .block();
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to