{"record":{"id":"f3ef6db6e74b7878","repo":"didi/DoKit","slug":"mdb-null-mdb-mockapidao","errorCode":null,"errorMessage":"mDb == null || mDb.mockApiDao()","messagePattern":"mDb == null \\|\\| mDb\\.mockApiDao\\(\\)","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/room_db/DokitDbManager.java","lineNumber":90,"sourceCode":"        private static DokitDbManager INSTANCE = new DokitDbManager();\n    }\n\n    public static DokitDbManager getInstance() {\n        return DokitDbManager.Holder.INSTANCE;\n    }\n\n    /**\n     * 获取所有的mock intercept apis\n     */\n    public void getAllInterceptApis() {\n        ThreadUtils.executeByIo(new ThreadUtils.SimpleTask<List<T>>() {\n            @Override\n            public List<T> doInBackground() throws Throwable {\n                DokitDatabase db = DoKitViewManager.getINSTANCE().getDb();\n                if (db.mockApiDao() != null) {\n                    return (List<T>) db.mockApiDao().getAllInterceptApi();\n                } else {\n                    throw new NullPointerException(\"mDb == null || mDb.mockApiDao()\");\n                }\n            }\n\n            @Override\n            public void onSuccess(List<T> result) {\n                list2mapByIntercept(result);\n            }\n\n            @Override\n            public void onFail(Throwable t) {\n                super.onFail(t);\n                LogHelper.e(TAG, \"error====>\" + t.getMessage());\n            }\n        });\n    }\n\n\n    /**","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/room_db/DokitDbManager.java#L72-L108","documentation":"Thrown inside DokitDbManager.getAllInterceptApis()'s background task when DoKitViewManager.getINSTANCE().getDb() returns null or the database's mockApiDao() is null. The message 'mDb == null || mDb.mockApiDao()' reflects both failure modes, but note the code itself dereferences db without a null check, so a null db actually NPEs at db.mockApiDao() first. The task runs on an IO thread via ThreadUtils; the throwable is delivered to onFail and logged, not rethrown to the caller.","triggerScenarios":"Calling getAllInterceptApis() before the DoKit database has been initialized (DoKitViewManager.getINSTANCE().getDb() still null), typically at app startup or when DoKit was not fully installed; Room DAO creation failed or the DB schema/version migration failed, leaving mockApiDao() null","commonSituations":"Code or another kit querying mock-intercept data during Application.onCreate before DoKit init completes; DoKit installed but the DokitDatabase Room build threw earlier (schema/migration issue), leaving a half-initialized state; Race between DB init thread and the first query","solutions":["Ensure DoraemonKit.install(...) has completed and the DB is set before invoking mock data queries — check DoKitViewManager.getINSTANCE().getDb() != null first","Retry the call after DB initialization completes, or defer it with a listener/post-init callback","If mockApiDao() itself is null, inspect logcat for the earlier Room initialization/migration failure and fix that root cause"],"exampleFix":"// before\ndokitDbManager.getAllInterceptApis(); // may run before db init\n\n// after\nif (DoKitViewManager.getINSTANCE().getDb() != null) {\n    dokitDbManager.getAllInterceptApis();\n} else {\n    LogHelper.e(TAG, \"DoKit db not ready; skip mock intercept query\");\n}","handlingStrategy":"validation","validationCode":"DokitDatabase db = DoKitViewManager.getINSTANCE().getDb();\nif (db != null && db.mockApiDao() != null) {\n    dokitDbManager.getAllInterceptApis();\n}","typeGuard":"boolean dbReady() { DokitDatabase db = DoKitViewManager.getINSTANCE().getDb(); return db != null && db.mockApiDao() != null; }","tryCatchPattern":null,"preventionTips":["Never query DoKit mock DB before DoraemonKit.install completes","Watch onFail/LogHelper output — these background NPEs surface as logs, not crashes"],"tags":["android","database","initialization","race-condition"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}