Tencent/QMUI_Android · warning · RuntimeException

Error to get FragmentEffectHandler's generic parameter type

Error message

Error to get FragmentEffectHandler's generic parameter type

What it means

When resolving a QMUIFragmentEffectHandler's effect type via reflection (generic superclass parameter), getHandlerEffectType() can fail to determine the Class. If effectClz remains null and QMUIConfig.DEBUG is true, a RuntimeException is thrown; in release builds the failure is only logged via QMUILog.d and the effect type is left null, so the effect handler is silently not registered.

Solutions

  1. Declare the handler with an explicit generic parameter: class MyHandler extends QMUIFragmentEffectHandler<MyEffect> instead of a raw/anonymous class.
  2. Enable -keepattributes Signature in ProGuard/R8 rules so generic signatures survive minification.
  3. Check QMUIConfig.DEBUG handling: in release the error is only logged — turn on debug or inspect logcat for 'Error to get FragmentEffectHandler's generic parameter type' to find the offending handler.
  4. Register concrete, non-anonymous handler classes and update QMUI if a known reflective resolution bug applies.

Example fix

// before
QMUIFragmentEffectHandler handler = new QMUIFragmentEffectHandler() { ... }; // raw/anonymous
// after
class MyEffectHandler extends QMUIFragmentEffectHandler<MyFragmentEffect> {
    @Override public void handle(MyFragmentEffect effect) { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure the handler class declares a concrete generic parameter at registration time
if (handlerClass.getGenericSuperclass() instanceof ParameterizedType) {
    registry.register(handlerClass);
} else {
    Log.w(TAG, handlerClass + " lacks a generic effect parameter; it will not resolve");
}

Type guard

boolean hasConcreteEffectType(Class<?> handler) {
    return handler.getGenericSuperclass() instanceof ParameterizedType;
}

Try / catch

try {
    registry.register(handlerClass);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("generic parameter type")) {
        Log.e(TAG, "Handler " + handlerClass + " missing generic effect type", e);
    } else throw e;
}

Prevention

When it happens

Trigger: Declaring a FragmentEffectHandler whose generic effect type cannot be resolved — e.g. a handler not parameterized with a concrete QMUIFragmentEffect subtype, anonymous/raw subclasses where generics are erased or absent, or exotic classloader/obfuscation setups that strip signatures.

Common situations: Debug builds where a handler class was written as raw type or without the generic parameter, R8 stripping Signature attributes, or registering handlers via reflection/anonymous classes losing the generic superclass.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06). Data as JSON: /api/errors/0439453ff3b5ad0a. Report an issue: GitHub.

Appendix: source

Thrown at arch/src/main/java/com/qmuiteam/qmui/arch/effect/QMUIFragmentEffectRegistry.java:204

                while (handlerCls != null && handlerCls.getSuperclass() != QMUIFragmentEffectHandler.class) {
                    handlerCls = handlerCls.getSuperclass();
                }
                if (handlerCls != null) {
                    Type type = handlerCls.getGenericSuperclass();
                    if (type instanceof ParameterizedType) {
                        Type[] params = ((ParameterizedType) type).getActualTypeArguments();
                        if (params.length > 0) {
                            effectClz = (Class<? extends Effect>) params[0];
                        }
                    }
                }
            } catch (Throwable ignore) {

            }

            if (effectClz == null) {
                if (QMUIConfig.DEBUG) {
                    throw new RuntimeException("Error to get FragmentEffectHandler's generic parameter type");
                } else {
                    QMUILog.d(TAG, "Error to get FragmentEffectHandler's generic parameter type");
                }
            }

            return effectClz;
        }

        @SuppressWarnings("unchecked")
        boolean shouldHandleEffect(Effect effect) {
            return mEffectType != null && mEffectType.isAssignableFrom(effect.getClass()) && mHandler.shouldHandleEffect((T) effect);
        }

        @MainThread
        @SuppressWarnings("unchecked")
        void pushOrHandleEffect(Effect effect) {
            QMUIFragmentEffectHandler.HandlePolicy policy = mHandler.provideHandlePolicy();
            if (policy == QMUIFragmentEffectHandler.HandlePolicy.Immediately ||

View on GitHub (pinned to 026e7d4866)