diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java index 778301a27..76ae9258b 100644 --- a/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/BaseEventEncoder.java @@ -1,7 +1,7 @@ package nostr.event.json.codec; +import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; -import lombok.SneakyThrows; import nostr.base.Encoder; import nostr.event.BaseEvent; @@ -16,8 +16,11 @@ public BaseEventEncoder(T event) { @Override // TODO: refactor all methods calling this to properly handle invalid json exception - @SneakyThrows public String encode() { - return ENCODER_MAPPER_BLACKBIRD.writeValueAsString(event); + try { + return ENCODER_MAPPER_BLACKBIRD.writeValueAsString(event); + } catch (JsonProcessingException e) { + throw new EventEncodingException("Failed to encode event to JSON", e); + } } } diff --git a/nostr-java-event/src/main/java/nostr/event/json/codec/EventEncodingException.java b/nostr-java-event/src/main/java/nostr/event/json/codec/EventEncodingException.java new file mode 100644 index 000000000..493a344ec --- /dev/null +++ b/nostr-java-event/src/main/java/nostr/event/json/codec/EventEncodingException.java @@ -0,0 +1,7 @@ +package nostr.event.json.codec; + +import lombok.experimental.StandardException; + +@StandardException +public class EventEncodingException extends RuntimeException { +} diff --git a/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java b/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java index aa1e5da09..fc4cace08 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/CanonicalAuthenticationMessage.java @@ -14,6 +14,7 @@ import nostr.event.impl.CanonicalAuthenticationEvent; import nostr.event.impl.GenericEvent; import nostr.event.json.codec.BaseEventEncoder; +import nostr.event.json.codec.EventEncodingException; import nostr.event.tag.GenericTag; import java.util.List; @@ -39,11 +40,15 @@ public CanonicalAuthenticationMessage(CanonicalAuthenticationEvent event) { @Override public String encode() throws JsonProcessingException { - return ENCODER_MAPPER_BLACKBIRD.writeValueAsString( - JsonNodeFactory.instance.arrayNode() - .add(getCommand()) - .add(ENCODER_MAPPER_BLACKBIRD.readTree( - new BaseEventEncoder<>(getEvent()).encode()))); + try { + return ENCODER_MAPPER_BLACKBIRD.writeValueAsString( + JsonNodeFactory.instance.arrayNode() + .add(getCommand()) + .add(ENCODER_MAPPER_BLACKBIRD.readTree( + new BaseEventEncoder<>(getEvent()).encode()))); + } catch (EventEncodingException e) { + throw new IllegalStateException("Failed to encode canonical authentication event", e); + } } @SneakyThrows diff --git a/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java b/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java index 0c3e3bceb..75af5ac4f 100644 --- a/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java +++ b/nostr-java-event/src/main/java/nostr/event/message/EventMessage.java @@ -14,6 +14,7 @@ import nostr.event.BaseMessage; import nostr.event.impl.GenericEvent; import nostr.event.json.codec.BaseEventEncoder; +import nostr.event.json.codec.EventEncodingException; import java.util.Map; import java.util.Objects; @@ -52,8 +53,12 @@ public String encode() throws JsonProcessingException { var arrayNode = JsonNodeFactory.instance.arrayNode().add(getCommand()); Optional.ofNullable(getSubscriptionId()) .ifPresent(arrayNode::add); - arrayNode.add(ENCODER_MAPPER_BLACKBIRD.readTree( - new BaseEventEncoder<>((BaseEvent) getEvent()).encode())); + try { + arrayNode.add(ENCODER_MAPPER_BLACKBIRD.readTree( + new BaseEventEncoder<>((BaseEvent) getEvent()).encode())); + } catch (EventEncodingException e) { + throw new IllegalStateException("Failed to encode event", e); + } return ENCODER_MAPPER_BLACKBIRD.writeValueAsString(arrayNode); } diff --git a/nostr-java-event/src/test/java/nostr/event/json/codec/BaseEventEncoderTest.java b/nostr-java-event/src/test/java/nostr/event/json/codec/BaseEventEncoderTest.java new file mode 100644 index 000000000..6a8ef3833 --- /dev/null +++ b/nostr-java-event/src/test/java/nostr/event/json/codec/BaseEventEncoderTest.java @@ -0,0 +1,46 @@ +package nostr.event.json.codec; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import nostr.event.BaseEvent; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class BaseEventEncoderTest { + + static class FailingSerializer extends JsonSerializer { + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + throw new IOException("Serialization failure"); + } + } + + static class FailingEvent extends BaseEvent { + @JsonSerialize(using = FailingSerializer.class) + public String getAttr() { + return "boom"; + } + + @Override + public String getId() { + return ""; + } + + @Override + public String toBech32() { + return ""; + } + } + + @Test + // Ensures encode throws EventEncodingException when serialization fails + void encodeThrowsEventEncodingException() { + var encoder = new BaseEventEncoder<>(new FailingEvent()); + assertThrows(EventEncodingException.class, encoder::encode); + } +}