msgpack-java
msgpack-java copied to clipboard
Writing null instead of throwing exception when serializing too big integer
MessagePacker#packBigInteger(BigInteger)
throws IllegalArgumentException
if given integer is bigger than maximum value of uint64 or smaller than minimum value of int64. This behavior itself is OK but error handling is difficult when I want to convert a nested JSON to MessagePack.
In my use case, I want to keep most of regular fields in the JSON while setting null to the invalid too big integer field. Currently, I'm converting JSON into org.msgpack.value.Value
instance first. This conversion works successfully even if the JSON contains too big integer. Then, when I call MessagePacker#packValue(Value)
method, it throws an exception. When I catch an exception, I want to write null instead but the invalid value is deep nested in the Value.
I would like to customize the handler when MessagePacker got too small/big integer.
A solution is adding an error handler to PackerConfig and MessagePacker calls it with the BigInteger and MessagePacker instance. The default handler will throw IllegalArgumentException. Users may set other handlers that write NULL instead and show logs, or throw other exceptions.
Another approach is adding a flag instead of handler to PackerConfig. Flag is an enum which can be EXCEPTION or NULL. If it is NULL, MessagePacker writes null instead of throwing IllegalArgumentException. This approach is mostly good but this can't satisfy a requirement where users want to show some warning logs as well as converting the too big/small integer to NULL.
public class MessagePack
{
public interface IllegalBigIntegerHandler
{
void handle(MessagePacker packer, BigInteger bi);
}
public static class PackerConfig
{
...
private IllegalBigIntegerHandler = (packer, bi) -> { throw new IllegalArgumentException("MessagePack cannot serialize BigInteger larger than 2^64-1"); }
public PackerConfig withIllegalBigIntegerHandler(IllegalBigIntegerHandler handler) { ... }
}
}
- Using void return type for the handler is ok since it will be called inside MessagePacker
- Using lambda notation is a concern since MessagePack is still built for Java7.
- IllegalBigIntegerHandler -> IntegerOverflowHandler might be a better naming to make clear how illegal the value is.
And also we should provide three types of handlers:
- REPORT_ERROR (default)
- CONVERT_TO_NULL (your approach)
- CONVERT_TO_STRING (use a string representation of the big integer value)