{"record":{"id":"0439453ff3b5ad0a","repo":"Tencent/QMUI_Android","slug":"error-to-get-fragmenteffecthandler-s-generic-param","errorCode":null,"errorMessage":"Error to get FragmentEffectHandler's generic parameter type","messagePattern":"Error to get FragmentEffectHandler's generic parameter type","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"arch/src/main/java/com/qmuiteam/qmui/arch/effect/QMUIFragmentEffectRegistry.java","lineNumber":204,"sourceCode":"                while (handlerCls != null && handlerCls.getSuperclass() != QMUIFragmentEffectHandler.class) {\n                    handlerCls = handlerCls.getSuperclass();\n                }\n                if (handlerCls != null) {\n                    Type type = handlerCls.getGenericSuperclass();\n                    if (type instanceof ParameterizedType) {\n                        Type[] params = ((ParameterizedType) type).getActualTypeArguments();\n                        if (params.length > 0) {\n                            effectClz = (Class<? extends Effect>) params[0];\n                        }\n                    }\n                }\n            } catch (Throwable ignore) {\n\n            }\n\n            if (effectClz == null) {\n                if (QMUIConfig.DEBUG) {\n                    throw new RuntimeException(\"Error to get FragmentEffectHandler's generic parameter type\");\n                } else {\n                    QMUILog.d(TAG, \"Error to get FragmentEffectHandler's generic parameter type\");\n                }\n            }\n\n            return effectClz;\n        }\n\n        @SuppressWarnings(\"unchecked\")\n        boolean shouldHandleEffect(Effect effect) {\n            return mEffectType != null && mEffectType.isAssignableFrom(effect.getClass()) && mHandler.shouldHandleEffect((T) effect);\n        }\n\n        @MainThread\n        @SuppressWarnings(\"unchecked\")\n        void pushOrHandleEffect(Effect effect) {\n            QMUIFragmentEffectHandler.HandlePolicy policy = mHandler.provideHandlePolicy();\n            if (policy == QMUIFragmentEffectHandler.HandlePolicy.Immediately ||","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/Tencent/QMUI_Android/blob/026e7d486677d6593a96689cd590ec3561176717/arch/src/main/java/com/qmuiteam/qmui/arch/effect/QMUIFragmentEffectRegistry.java#L186-L222","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Declare the handler with an explicit generic parameter: class MyHandler extends QMUIFragmentEffectHandler<MyEffect> instead of a raw/anonymous class.","Enable -keepattributes Signature in ProGuard/R8 rules so generic signatures survive minification.","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.","Register concrete, non-anonymous handler classes and update QMUI if a known reflective resolution bug applies."],"exampleFix":"// before\nQMUIFragmentEffectHandler handler = new QMUIFragmentEffectHandler() { ... }; // raw/anonymous\n// after\nclass MyEffectHandler extends QMUIFragmentEffectHandler<MyFragmentEffect> {\n    @Override public void handle(MyFragmentEffect effect) { ... }\n}","handlingStrategy":"validation","validationCode":"// ensure the handler class declares a concrete generic parameter at registration time\nif (handlerClass.getGenericSuperclass() instanceof ParameterizedType) {\n    registry.register(handlerClass);\n} else {\n    Log.w(TAG, handlerClass + \" lacks a generic effect parameter; it will not resolve\");\n}","typeGuard":"boolean hasConcreteEffectType(Class<?> handler) {\n    return handler.getGenericSuperclass() instanceof ParameterizedType;\n}","tryCatchPattern":"try {\n    registry.register(handlerClass);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"generic parameter type\")) {\n        Log.e(TAG, \"Handler \" + handlerClass + \" missing generic effect type\", e);\n    } else throw e;\n}","preventionTips":["Always subclass QMUIFragmentEffectHandler with a concrete effect type parameter","Add -keepattributes Signature to keep generics under R8","Avoid raw or anonymous handler classes","Run registration flows in debug builds where the failure throws instead of logging"],"tags":["android","reflection","generics","effects"],"backgroundTag":"internal-invariant-violation","analyzedSha":"026e7d486677d6593a96689cd590ec3561176717","analyzedAt":"2026-09-06T13:32:24.816Z","contentChangedAt":"2026-09-06T13:32:24.816Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}