YunaiV/ruoyi-vue-pro · error · RuntimeException
[createDecodeParser][解析异常]
Error message
[createDecodeParser][解析异常]
What it means
The Vert.x RecordParser.exceptionHandler for the delimiter-based codec rethrows any parser error as RuntimeException. For this codec the realistic trigger is a record exceeding MAX_RECORD_SIZE (64KB): a device streams data without ever emitting the configured delimiter, so the parser buffers past the cap and fires the exception handler.
Source
Thrown at yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/codec/delimiter/IotTcpDelimiterFrameCodec.java:58
public IotTcpDelimiterFrameCodec(IotTcpConfig.CodecConfig config) {
Assert.notBlank(config.getDelimiter(), "delimiter 不能为空");
this.delimiterBytes = parseDelimiter(config.getDelimiter());
}
@Override
public IotTcpCodecTypeEnum getType() {
return IotTcpCodecTypeEnum.DELIMITER;
}
@Override
public RecordParser createDecodeParser(Handler<Buffer> handler) {
RecordParser parser = RecordParser.newDelimited(Buffer.buffer(delimiterBytes));
parser.maxRecordSize(MAX_RECORD_SIZE); // 设置最大记录大小,防止 DoS 攻击
// 处理完整消息(不包含分隔符)
parser.handler(handler);
parser.exceptionHandler(ex -> {
throw new RuntimeException("[createDecodeParser][解析异常]", ex);
});
return parser;
}
@Override
public Buffer encode(byte[] data) {
Buffer buffer = Buffer.buffer();
buffer.appendBytes(data);
buffer.appendBytes(delimiterBytes);
return buffer;
}
/**
* 解析分隔符字符串为字节数组
* <p>
* 支持转义字符:\n、\r、\r\n、\t
*
* @param delimiter 分隔符字符串View on GitHub (pinned to 0418084e22)
Solutions
- Confirm the configured delimiter (config.delimiter, supporting \n \r \r\n \t or custom) exactly matches the device's frame terminator — capture traffic with Wireshark/tcpdump to verify.
- If legitimate frames exceed 64KB, raise MAX_RECORD_SIZE (and ensure memory headroom).
- Close or rate-limit the offending connection when the handler fires repeatedly; the exception is thrown on the event loop so add metrics/alerts.
- Note: throwing inside exceptionHandler propagates up Vert.x — prefer logging + socket.close() instead of rethrowing to avoid killing the event loop.
Example fix
// before (rethrow can disrupt the Vert.x handler pipeline)
parser.exceptionHandler(ex -> {
throw new RuntimeException("[createDecodeParser][解析异常]", ex);
});
// after (log + close socket, do not rethrow on event loop)
parser.exceptionHandler(ex -> {
log.error("[createDecodeParser][解析异常]", ex);
// signal the owning socket to close
}); Defensive patterns
Strategy: try-catch
Validate before calling
// validate the configured delimiter matches observed traffic before relying on the codec
byte[] expected = parseDelimiter(config.getDelimiter());
if (expected.length == 0) {
throw new IllegalArgumentException("分隔符不能为空");
} Try / catch
// log + close the offending socket instead of rethrowing on the Vert.x event loop
parser.exceptionHandler(ex -> {
log.error("[createDecodeParser][解析异常]", ex);
// signal connection manager to close this socket
}); Prevention
- Confirm the delimiter exactly matches the device's frame terminator (capture with tcpdump/Wireshark).
- If legitimate frames exceed 64KB, raise MAX_RECORD_SIZE and provision memory.
- Do not rethrow inside exceptionHandler — it disrupts the Vert.x pipeline; log and close the socket.
- Monitor per-connection parse-error rates to detect misbehaving devices.
When it happens
Trigger: Device sends a continuous byte stream that never contains the configured delimiter, crossing 64KB; wrong delimiter configured (device terminates with \n but config says \r\n); a malformed/buggy device flooding garbage; delimiter bytes split across TCP segments in a way that never reassembles (rare with Vert.x).
Common situations: Delimiter mismatch between device firmware and gateway config; device firmware forgot to append the delimiter; malicious device; baud-rate/garbage on a serial-to-TCP converter.
Related errors
- [createDecodeParser][解析异常]
- [createDecodeParser][解析异常]
- 数据长度 %d 超过固定长度 %d
- [createDecodeParser][帧长度异常,length: %d, frameBodyLength: %d]
- [createDecodeParser][消息体不能为空]
AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14).
Data as JSON: /api/errors/30626d96684cf03f.
Report an issue: GitHub.