YunaiV/ruoyi-vue-pro · error · IllegalArgumentException

不支持的功能码: {}

Error message

不支持的功能码: {}

What it means

createReadRequest() only accepts the four Modbus read function codes: FC1 (read coils), FC2 (read discrete inputs), FC3 (read holding registers), FC4 (read input registers). Any other integer value hits the default branch and throws IllegalArgumentException. This means the point/device config supplied a functionCode outside {1,2,3,4} for a read operation.

Source

Thrown at yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/modbus/common/utils/IotModbusTcpClientUtils.java:141

        });
    }

    /**
     * 创建读取请求
     */
    @SuppressWarnings("EnhancedSwitchMigration")
    private static ModbusRequest createReadRequest(Integer functionCode, Integer address, Integer count) {
        switch (functionCode) {
            case FC_READ_COILS:
                return new ReadCoilsRequest(address, count);
            case FC_READ_DISCRETE_INPUTS:
                return new ReadInputDiscretesRequest(address, count);
            case FC_READ_HOLDING_REGISTERS:
                return new ReadMultipleRegistersRequest(address, count);
            case FC_READ_INPUT_REGISTERS:
                return new ReadInputRegistersRequest(address, count);
            default:
                throw new IllegalArgumentException("不支持的功能码: " + functionCode);
        }
    }

    /**
     * 创建写入请求
     */
    @SuppressWarnings("EnhancedSwitchMigration")
    private static ModbusRequest createWriteRequest(Integer functionCode, Integer address, Integer count, int[] values) {
        switch (functionCode) {
            case FC_READ_COILS: // 写线圈(使用功能码 5 或 15)
                if (count == 1) {
                    return new WriteCoilRequest(address, values[0] != 0);
                } else {
                    BitVector bv = new BitVector(count);
                    for (int i = 0; i < Math.min(values.length, count); i++) {
                        bv.setBit(i, values[i] != 0);
                    }
                    return new WriteMultipleCoilsRequest(address, bv);

View on GitHub (pinned to 0418084e22)

Solutions

  1. Set the point functionCode to 1, 2, 3, or 4 (the standard Modbus read codes) per the device register map.
  2. Add config-load validation rejecting points whose functionCode is not in {1,2,3,4} for read points.
  3. If the device uses a custom function code (e.g. FC65), use a protocol variant that supports it (the Modbus TCP Server protocol uses a custom FC for auth) rather than the generic read path.
Defensive patterns

Strategy: validation

Validate before calling

// before reading, ensure the function code is a supported read code
if (functionCode == null || functionCode < 1 || functionCode > 4) {
    throw new IllegalArgumentException("读取功能码必须在 1-4 之间, 当前: " + functionCode);
}

Type guard

boolean isSupportedReadFc(Integer fc) {
    return fc != null && fc >= 1 && fc <= 4;
}

Prevention

When it happens

Trigger: point.getFunctionCode() returns a write FC (5,6,15,16), 0 (default/unset), null auto-unboxed to NPE (caught upstream then re-wrapped), or any non-standard code; a read is then attempted.

Common situations: Device config accidentally uses a write function code for a read point; functionCode column defaulted to 0 in the DB; vendor uses a non-standard/custom function code for reads.

Related errors


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