记一次报错
今天遇到一个错误,启动应用时,直接崩溃,报错
Stacktrace:
SourceMap is not initialized yet
at PreferenceModel (entry|entry|1.0.0|src/main/ets/utils/PreferenceModel.ts:30:56)
at func_main_0 (entry|entry|1.0.0|src/main/ets/utils/PreferenceModel.ts:187:16)
//PreferenceModel.ets 文件结构
class PreferenceModel {
}
const SpUtil = new PreferenceModel();
export default SpUtil;
PreferenceModel是用于记录应用配置项的一个类,这里是由于在PreferenceModel的构造函数中获取保存的context失败,导致异常。
但是问题在于:
- context是直接在应用的入口EntryAbility.onCreate()进行保存的不应该失败
- 在应用的启动入口处没有调用PreferenceModel的方法
- 在出问题前后PreferenceModel没有任何修改
后面发现PreferenceModel的初始化早于EntryAbility.onCreate。
这就很奇怪。
后面通过版本控制,一个文件一个文件的回滚,找到问题
//在Util.ets文件中
import { loginFromSplash } from '../pages/account/LoginPage';
export class Utils {
static finishPageAndLogin(ctx: UIContext) {
// ctx.getRouter().clear();
// Utils.replaceUrl(ctx, { url: "pages/account/LoginPage", params: { param: LoginFrom.SPLASH } });
loginFromSplash(ctx);
}
}
//在LoginPage.ets文件中
export function loginFromSplash(ctx: UIContext) {
ctx.getRouter().clear();
Utils.replaceUrl(ctx, { url: "pages/account/LoginPage", params: { param: LoginFrom.SPLASH } });
}
struct LoginPage {}
问题出在finishPageAndLogin()方法,注释的是没问题的代码,loginFromSplash()是出问题的代码。
loginFromSplash()这个方法在应用入口处也完全没有调用,为什么会有问题。
原因:因为在应用入口处有使用Utils,会导致Utils文件中的所有import立即执行,又由于finishPageAndLogin()函数调用loginFromSplash(),导致LoginPage加载,LoginPage中又使用LoginViewModel类,LoginViewModel中有import SpUtil from '../utils/PreferenceModel';
那么也就是虽然在应用入口处,没有调用上述任何一个方法,但是由于import链
Utils.ets
└── import LoginPage.ets
└── import LoginViewModel.ets
└── import SpUtil (PreferenceModel.ets)
└── new PreferenceModel()
└── 获取 context 失败!💥
导致了这个问题发生。
那么如何防御这种问题,根据ai回答:工具类不用import 页面,避免将整个页面依赖树拖进来。