heibaiying/BigData-Notes · error · IllegalArgumentException

Cannot process such data type: ${dataType}

Error message

Cannot process such data type: ${dataType}

What it means

This IllegalArgumentException is the default branch of the data-type switch in the Redis store bolt's process() method (pattern of Storm's RedisStoreBolt): every RedisDataTypeDescription.RedisDataType case that the bolt knows how to persist (STRING, HASH, SORTED_SET, HYPER_LOG_LOG, GEO, etc.) has an explicit handler, and any other value falls through to this throw. It means the store mapper declared a data type the persistence logic does not support, so the tuple cannot be written to Redis. The exception is caught, reported to the topology, and the tuple is failed.

Source

Thrown at notes/Storm集成Redis详解.md:422

                    break;

                case HYPER_LOG_LOG:
                    jedisCommand.pfadd(key, value);
                    break;

                case GEO:
                    String[] array = value.split(":");
                    if (array.length != 2) {
                        throw new IllegalArgumentException("value structure should be longitude:latitude");
                    }

                    double longitude = Double.valueOf(array[0]);
                    double latitude = Double.valueOf(array[1]);
                    jedisCommand.geoadd(additionalKey, longitude, latitude, key);
                    break;

                default:
                    throw new IllegalArgumentException("Cannot process such data type: " + dataType);
            }

            collector.ack(input);
        } catch (Exception e) {
            this.collector.reportError(e);
            this.collector.fail(input);
        } finally {
            returnInstance(jedisCommand);
        }
    }

     .........
}

```

### 3.3 JedisCommands

View on GitHub (pinned to 3898939aca)

Solutions

  1. Align the mapper's declared data type with one the switch actually handles — pick STRING, HASH, SORTED_SET, HYPER_LOG_LOG, or GEO per your access pattern.
  2. If you need a type the copied switch lacks (e.g. LIST via rpush, SET via sadd), add the case to the switch: case LIST: jedisCommand.rpush(additionalKey, value); break; — this code is yours to extend.
  3. Prefer the official org.apache.storm.redis.bolt.RedisStoreBolt from the storm-redis artifact over vendored copies so you inherit full enum coverage; if the vendored copy exists for learning, keep its switch in sync when upgrading Storm.
  4. Add a startup assertion in prepare() that rejects unsupported data types at topology launch instead of failing on the first tuple.

Example fix

// before: mapper declares a type with no case in the switch
new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.LIST, "mylist");
// -> default: throw new IllegalArgumentException("Cannot process such data type: " + dataType);

// after: add the missing case to the vendored bolt
switch (dataType) {
    case LIST:
        jedisCommand.rpush(additionalKey, value);
        break;
    // ...existing cases...
}
Defensive patterns

Strategy: validation

Validate before calling

Set<RedisDataTypeDescription.RedisDataType> supported =
    EnumSet.of(STRING, HASH, SORTED_SET, HYPER_LOG_LOG, GEO /* cases present in your switch */);
if (!supported.contains(dataType)) {
    throw new IllegalArgumentException("Unsupported data type " + dataType + "; supported: " + supported);
}

Type guard

boolean isSupportedStoreType(org.apache.storm.redis.common.mapper.RedisDataTypeDescription.RedisDataType t) {
    switch (t) {
        case STRING: case HASH: case SORTED_SET: case HYPER_LOG_LOG: case GEO:
            return true;
        default:
            return false;
    }
}

Try / catch

// Validate in prepare() rather than catching per-tuple: fail the topology at launch
if (!isSupportedStoreType(dataType)) {
    throw new IllegalArgumentException("Cannot process such data type: " + dataType);
}
// The per-tuple catch (reportError + fail) in process() remains as a safety net only.

Prevention

When it happens

Trigger: Calling setDataTypeDescription()/getDataTypeDescription() with a RedisDataType value not covered by the switch — typically because the code was compiled against a newer storm-redis where RedisDataType gained new enum constants (or a custom enum value) that this bolt's switch does not handle; or the switch itself was trimmed during copy-paste so legitimate types (e.g. LIST, SET, HASH) are missing. It fires per-tuple: the first tuple with the unsupported type triggers it.

Common situations: Vendoring/copying RedisStoreBolt source into your project (as this repo's notes do) and not porting every case; upgrading storm-redis to a version whose RedisDataType enum includes types your copied switch never handled; declaring a data type in the mapper that was never wired into the bolt ('STRING' vs custom constants); mixed pipelines where one mapper is reused across bolts with different switch coverage.

Related errors


AI-assisted analysis of heibaiying/BigData-Notes@3898939aca (2026-08-14). Data as JSON: /api/errors/9df3fd7993a8e72a. Report an issue: GitHub.