msgpack-java icon indicating copy to clipboard operation
msgpack-java copied to clipboard

Writing null instead of throwing exception when serializing too big integer

Open frsyuki opened this issue 7 years ago • 4 comments

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.

frsyuki avatar Mar 01 '17 21:03 frsyuki

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.

frsyuki avatar Mar 01 '17 22:03 frsyuki

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) { ... }
    }
}

frsyuki avatar Mar 01 '17 22:03 frsyuki

  • 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.

xerial avatar Mar 02 '17 20:03 xerial

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)

xerial avatar Mar 02 '17 20:03 xerial