YunaiV/ruoyi-vue-pro · error · RuntimeException
[createDecodeParser][解析异常]
Error message
[createDecodeParser][解析异常]
What it means
The Vert.x RecordParser.exceptionHandler for the fixed-length codec rethrows any parser error as RuntimeException. A fixed-length parser rarely errors on its own, so this typically surfaces an underlying Vert.x buffer/state issue or a parser reused incorrectly. The handler wraps whatever Throwable the parser reports.
Source
Thrown at yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/codec/length/IotTcpFixedLengthFrameCodec.java:42
*/
private final int fixedLength;
public IotTcpFixedLengthFrameCodec(IotTcpConfig.CodecConfig config) {
Assert.notNull(config.getFixedLength(), "fixedLength 不能为空");
this.fixedLength = config.getFixedLength();
}
@Override
public IotTcpCodecTypeEnum getType() {
return IotTcpCodecTypeEnum.FIXED_LENGTH;
}
@Override
public RecordParser createDecodeParser(Handler<Buffer> handler) {
RecordParser parser = RecordParser.newFixed(fixedLength);
parser.handler(handler);
parser.exceptionHandler(ex -> {
throw new RuntimeException("[createDecodeParser][解析异常]", ex);
});
return parser;
}
@Override
public Buffer encode(byte[] data) {
// 校验数据长度不能超过固定长度
if (data.length > fixedLength) {
throw new IllegalArgumentException(String.format(
"数据长度 %d 超过固定长度 %d", data.length, fixedLength));
}
Buffer buffer = Buffer.buffer(fixedLength);
buffer.appendBytes(data);
// 如果数据不足固定长度,填充 0(RecordParser.newFixed 解码时按固定长度读取,所以发送端需要填充)
if (data.length < fixedLength) {
byte[] padding = new byte[fixedLength - data.length];
buffer.appendBytes(padding);
}View on GitHub (pinned to 0418084e22)
Solutions
- Ensure each connection gets its own createDecodeParser() instance (do not cache/share a RecordParser across NetSockets).
- Upgrade/align the Vert.x version if a parser bug is suspected (check Vert.x release notes).
- Log the cause and close the socket rather than rethrowing on the event loop.
- Capture the exact payload that preceded the error to reproduce.
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure each connection gets its own parser instance (do not share across sockets) RecordParser parser = codec.createDecodeParser(frame -> handleFrame(socket, frame)); socket.handler(parser);
Try / catch
parser.exceptionHandler(ex -> {
log.error("[createDecodeParser][解析异常]", ex);
socket.close();
}); Prevention
- Never share a RecordParser/codec-stateful object across multiple NetSockets.
- Keep the Vert.x version aligned across modules.
- Log the cause and close the socket rather than rethrowing on the event loop.
When it happens
Trigger: Vert.x RecordParser internal error; parser invoked after being shared/closed incorrectly; a programmatic misuse triggering an internal IllegalStateException from the parser.
Common situations: Codec instance shared across sockets (not thread/connection safe); Vert.x version incompatibility; internal parser state corruption from misuse.
Related errors
- [createDecodeParser][解析异常]
- 数据长度 %d 超过固定长度 %d
- [createDecodeParser][解析异常]
- [createDecodeParser][帧长度异常,length: %d, frameBodyLength: %d]
- [createDecodeParser][消息体不能为空]
AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14).
Data as JSON: /api/errors/5e23d9c38aaf53b4.
Report an issue: GitHub.