YunaiV/ruoyi-vue-pro · error · RuntimeException

二进制消息编码失败: {}

Error message

二进制消息编码失败: {}

What it means

IotBinarySerializer.serialize wraps any Exception thrown while building a binary frame — determineMessageType, buildMessageBody, or buildCompleteMessage — and rethrows it as a RuntimeException whose message and cause carry the root failure. The method first asserts the message and its method field are non-null/non-blank (those throw IllegalArgumentException directly, NOT via this wrapper). So this specific wrapped error means the message passed preconditions but the binary encoding logic itself broke.

Source

Thrown at yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/serialize/binary/IotBinarySerializer.java:89

    @Override
    public IotSerializeTypeEnum getType() {
        return IotSerializeTypeEnum.BINARY;
    }

    @Override
    public byte[] serialize(IotDeviceMessage message) {
        Assert.notNull(message, "消息不能为空");
        Assert.notBlank(message.getMethod(), "消息方法不能为空");
        try {
            // 1. 确定消息类型
            byte messageType = determineMessageType(message);
            // 2. 构建消息体
            byte[] bodyData = buildMessageBody(message, messageType);
            // 3. 构建完整消息
            return buildCompleteMessage(message, messageType, bodyData);
        } catch (Exception e) {
            log.error("[encode][二进制消息编码失败,消息: {}]", message, e);
            throw new RuntimeException("二进制消息编码失败: " + e.getMessage(), e);
        }
    }

    @Override
    public IotDeviceMessage deserialize(byte[] bytes) {
        Assert.notNull(bytes, "待解码数据不能为空");
        Assert.isTrue(bytes.length >= MIN_MESSAGE_LENGTH, "数据包长度不足");
        try {
            Buffer buffer = Buffer.buffer(bytes);
            int index = 0;

            // 1. 验证魔术字
            byte magic = buffer.getByte(index++);
            Assert.isTrue(magic == MAGIC_NUMBER, "无效的协议魔术字: " + magic);

            // 2. 验证版本号
            byte version = buffer.getByte(index++);
            Assert.isTrue(version == PROTOCOL_VERSION, "不支持的协议版本: " + version);

View on GitHub (pinned to 0418084e22)

Solutions

  1. Read the logged cause (log.error "[encode][二进制消息编码失败" prints the full exception) — the wrapped Throwable identifies the real failing step.
  2. Ensure the IotDeviceMessage subclass you serialize is one the binary protocol knows how to encode (check determineMessageType covers it).
  3. Prefer IotSerializeTypeEnum.JSON for message types the binary serializer does not yet support.
  4. Add the missing message-type branch in buildMessageBody/determineMessageType and a round-trip serialize+deserialize unit test.

Example fix

// before
byte[] bytes = binarySerializer.serialize(message); // RuntimeException on encode

// after
byte[] bytes;
try {
    bytes = binarySerializer.serialize(message);
} catch (RuntimeException e) {
    log.error("[encode][failed for method {}]", message.getMethod(), e);
    bytes = jsonSerializer.serialize(message); // graceful fallback to JSON
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the message is one the binary protocol claims to support before serializing
if (message == null || StrUtil.isBlank(message.getMethod())) {
    throw new IllegalArgumentException("message/method required");
}
// If you have a known set of supported message types, check membership here:
// if (!SUPPORTED_BINARY_MESSAGE_TYPES.contains(message.getClass())) use JSON instead.

Try / catch

byte[] bytes;
try {
    bytes = binarySerializer.serialize(message);
} catch (RuntimeException e) {
    // e.getCause() holds the real encode failure (determineMessageType/buildMessageBody)
    log.error("[encode][binary serialize failed for {}]", message.getMethod(), e);
    bytes = jsonSerializer.serialize(message); // optional JSON fallback
}

Prevention

When it happens

Trigger: Passing an IotDeviceMessage whose method is present but whose data/type cannot be mapped by determineMessageType; a payload field exceeding the fixed-width binary layout limits; an IotDeviceMessage subclass unrecognized by buildMessageBody; numeric/length overflow while writing the Buffer.

Common situations: Introducing a new IotDeviceMessage subclass without extending determineMessageType/buildMessageBody; sending a message with fields that violate the binary protocol contract; encoding a method name longer than the wire format allows.

Related errors


AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14). Data as JSON: /api/errors/dd22e5676316504e. Report an issue: GitHub.