Application_Error VS OnException 遇到的坑

在工作中遇到一个巨坑,就是关于Application_Error和OnException,
     
     本身我的应用程序设置了全局异常OnException处理,手动抛出异常,OnException正常捕捉,但有一次我将一个方法,修改了一下,
 
 
结果就诡异了,请求返回状态码一直是500,但是异常并未捕捉到,百思不得其姐,然后就跟踪方法执行过程,发现我的业务代码正常执行并且返回,但是接收返回的状态还是500,然后就在Globle中使用Application_Error捕捉异常,竟然真的捕捉到了,
 
 
 
这样子才发现问题,但是还不明白为什么OnException捕捉不到呢?
 
 
请高手留下宝贵意见!谢谢。
 
 
 
 

转载于:https://www.cnblogs.com/simoncai/p/6259601.html

program Project_HIDComm; uses System.SysUtils, System.Classes, Vcl.Forms, Winapi.Windows, uMainForm in 'uMainForm.pas' {MainForm}, uHIDComm in 'uHIDComm.pas'; {$R *.res} { 全局异常处理器 } class procedure TMainForm.GlobalExceptionHandler(Sender: TObject; E: Exception); var Log: TStringList; begin Log := TStringList.Create; try Log.Add('===== ' + DateTimeToStr(Now) + ' ====='); Log.Add('异常类: ' + E.ClassName); Log.Add('错误: ' + E.Message); if FileExists('error.log') then Log.AddStrings(TStringList.Create.LoadFromFile('error.log')); Log.SaveToFile('error.log'); MessageBox(0, PChar('操作失败: '#13#10 + E.Message), '错误', MB_ICONERROR); finally Log.Free; end; end; begin Application.Initialize; Application.OnException := TMainForm.GlobalExceptionHandler; Application.CreateForm(TMainForm, MainForm); Application.Run; end. --- [dcc32 Hint] uHIDComm.pas(45): H2077 Value assigned to 'THIDComm.OpenDevice' never used [dcc32 Error] Project_HIDComm.dpr(14): E2003 Undeclared identifier: 'TMainForm' [dcc32 Error] Project_HIDComm.dpr(21): E2003 Undeclared identifier: 'E' [dcc32 Error] Project_HIDComm.dpr(21): E2125 EXCEPT or FINALLY expected [dcc32 Error] Project_HIDComm.dpr(24): E2066 Missing operator or semicolon [dcc32 Error] Project_HIDComm.dpr(25): E2250 There is no overloaded version of 'AddStrings' that can be called with these arguments [dcc32 Error] Project_HIDComm.dpr(28): E2029 ')' expected but identifier 'Message' found [dcc32 Error] Project_HIDComm.dpr(32): E2029 '.' expected but ';' found [dcc32 Error] Project_HIDComm.dpr(36): E2018 Record, object or class type required [dcc32 Error] Project_HIDComm.dpr(37): E2010 Incompatible types: 'TComponentClass' and 'procedure, untyped pointer or untyped parameter' 你真的会编程吗?
最新发布
10-01
我发现,只要你给的代码就没有一次能通过编译的,只要给代码编译错误必然一大堆! procedure GlobalExceptionHandler(Sender: TObject; E: Exception); begin // 记录异常到日志文件 AssignFile(LogFile, 'crash.log'); if not FileExists('crash.log') then Rewrite(LogFile) else Append(LogFile); Writeln(LogFile, '[' + DateTimeToStr(Now) + '] '); Writeln(LogFile, 'Exception class: ', E.ClassName); Writeln(LogFile, 'Exception message: ', E.Message); CloseFile(LogFile); // 显示错误信息 MessageBox(0, PChar('程序发生致命错误:' + E.Message), '错误', MB_ICONERROR); end; begin Application.Initialize; // Application.MainFormOnTaskbar := True; Application.OnException := GlobalExceptionHandler; // 设置全局异常处理 try Application.CreateForm(TMainForm, MainForm); except on E: Exception do begin // 创建主窗体失败,记录日志 AssignFile(LogFile, 'crash.log'); Append(LogFile); Writeln(LogFile, '[' + DateTimeToStr(Now) + '] 创建主窗体失败'); Writeln(LogFile, 'Exception class: ', E.ClassName); Writeln(LogFile, 'Exception message: ', E.Message); CloseFile(LogFile); MessageBox(0, PChar('创建主窗体失败:' + E.Message), '错误', MB_ICONERROR); Exit; end; end; [dcc32 Error] Project_HIDComm.dpr(13): E2003 Undeclared identifier: 'Exception' [dcc32 Error] Project_HIDComm.dpr(17): E2003 Undeclared identifier: 'FileExists' [dcc32 Error] Project_HIDComm.dpr(21): E2003 Undeclared identifier: 'DateTimeToStr' [dcc32 Error] Project_HIDComm.dpr(21): E2003 Undeclared identifier: 'Now' [dcc32 Error] Project_HIDComm.dpr(22): E2029 ',' or ')' expected but identifier 'ClassName' found [dcc32 Error] Project_HIDComm.dpr(33): E2009 Incompatible types: 'method pointer and regular procedure' [dcc32 Error] Project_HIDComm.dpr(38): E2005 'Exception' is not a type identifier [dcc32 Error] Project_HIDComm.dpr(43): E2003 Undeclared identifier: 'DateTimeToStr' [dcc32 Error] Project_HIDComm.dpr(43): E2003 Undeclared identifier: 'Now' [dcc32 Error] Project_HIDComm.dpr(44): E2029 ',' or ')' expected but identifier 'ClassName' found [dcc32 Error] Project_HIDComm.dpr(50): E2029 '.' expected but ';' found
10-01
鸿蒙 next export class CrashUtil { private constructor() {} private static readonly idKey: string = 'crash_observer_id_key' private static observerId: number = -100; private static ErrorFilePath: string = ''; //错误日志文件路径 /** * 注册错误观测器。注册后可以捕获到应用产生的js crash,应用崩溃时进程不会退出。将异常信息写入本地文件。 */ static onError() { try { let cacheId = GlobalContext.getContext().getObject(CrashUtil.idKey) as number; if (cacheId !== undefined && cacheId !== -100) { CrashUtil.offError(); //如果存在,就先注销错误观测器。 } CrashUtil.observerId = errorManager.on('error', { onUnhandledException(errMsg) { let errStr = `${DateUtil.getTodayStr()} - 异常信息:\n${errMsg}\n\n\n`; CrashUtil.ErrorFilePath = FileUtil.getFilesDirPath("ErrorLog", "errorLog.txt") FileUtil.writeEasy(CrashUtil.ErrorFilePath, errStr); }, onException(errObject) { // let errStr = `${DateUtil.getTodayStr()} - 异常信息2:\n${JSON.stringify(errObject)}\n\n\n`; } }); GlobalContext.getContext().setObject(CrashUtil.idKey, CrashUtil.observerId); } catch (err) { let error = err as BusinessError; LogUtil.error(`CrashUtil-onError-异常 ~ code: ${error.code} -·- message: ${error.message}`); } } /** * 注销错误观测器。 */ static offError() { try { if (CrashUtil.observerId === -100) { let cacheId = GlobalContext.getContext().getObject(CrashUtil.idKey) as number; if (cacheId && cacheId != -100) { CrashUtil.observerId = cacheId; } } errorManager.off('error', CrashUtil.observerId, (err: BusinessError) => { if (err) { LogUtil.error("CrashUtil:" + JSON.stringify(err)) return; } GlobalContext.getContext().setObject(CrashUtil.idKey, -100); }); } catch (err) { let error = err as BusinessError; LogUtil.error(`CrashUtil-offError-异常 ~ code: ${error.code} -·- message: ${error.message}`); } } /** * 导出错误日志 */ static onExportErrorLog() { if (StrUtil.isNotEmpty(CrashUtil.ErrorFilePath)) { PickerUtil.saveDocument(['errorLog.txt']).then((documentSaveResult: Array<string>) => { if (documentSaveResult && documentSaveResult.length > 0) { let saveUri = documentSaveResult[0]; FileUtil.copy(CrashUtil.ErrorFilePath, saveUri); } }) } else { ToastUtil.showToast("暂无日志文件"); } } /** * 读取错误日志文件 */ static async readErrorText(): Promise<string> { if (StrUtil.isNotEmpty(CrashUtil.ErrorFilePath)) { if (FileUtil.accessSync(CrashUtil.ErrorFilePath)) { return await FileUtil.readText(CrashUtil.ErrorFilePath); } } return ''; } /** * 启用应用恢复功能,参数按顺序填入。该接口调用后,应用从启动器启动时第一个Ability支持恢复。 * @param restart RestartFlag 应用重启标志。 * ALWAYS_RESTART 0 总是重启应用。 * RESTART_WHEN_JS_CRASH 0x0001 发生JS_CRASH时重启应用。 * RESTART_WHEN_APP_FREEZE 0x0002 发生APP_FREEZE时重启应用。 * NO_RESTART 0xFFFF 总是不重启应用。 * @param saveOccasion SaveOccasionFlag 保存条件标志 * SAVE_WHEN_ERROR 0x0001 当发生应用故障时保存。 * SAVE_WHEN_BACKGROUND 0x0002 当应用切入后台时保存。 * @param saveMode SaveModeFlag 状态保存标志 * SAVE_WITH_FILE 0x0001 每次状态保存都会写入到本地文件缓存。 * SAVE_WITH_SHARED_MEMORY 0x0002 状态先保存在内存中,应用故障退出时写入到本地文件缓存。 */ static enableAppRecovery(restart: appRecovery.RestartFlag = appRecovery.RestartFlag.ALWAYS_RESTART, saveOccasion: appRecovery.SaveOccasionFlag = appRecovery.SaveOccasionFlag.SAVE_WHEN_ERROR, saveMode: appRecovery.SaveModeFlag.SAVE_WITH_FILE = appRecovery.SaveModeFlag.SAVE_WITH_FILE) { appRecovery.enableAppRecovery(restart, saveOccasion, saveMode); } /** * 重启APP,并拉起应用启动时第一个Ability,可以配合errorManager相关接口使用。 * 如果该Ability存在已经保存的状态,这些状态数据会在Ability的OnCreate生命周期回调的want参数中作为wantParam属性传入。 * API10时将启动由setRestartWant指定的Ability。如果没有指定则按以下规则启动: * 如果当前应用前台的Ability支持恢复,则重新拉起该Ability。 * 如果存在多个支持恢复的Ability处于前台,则只拉起最后一个。 * 如果没有Ability处于前台,则不拉起。 */ static restartApp() { appRecovery.restartApp() } /** * 保存当前App状态 或 主动保存Ability的状态,这个状态将在下次恢复启动时使用。可以配合errorManager相关接口使用 * @param context UIAbilityContext 需要保存状态的UIAbility所对应的context。 * @returns */ static saveAppState(context?: common.UIAbilityContext): boolean { if (context) { return appRecovery.saveAppState(context) //主动保存Ability的状态 } else { return appRecovery.saveAppState() //保存当前App状态 } } /** * 设置下次恢复主动拉起场景下的Ability。该Ability必须为当前包下的UIAbility。 * @param want 通过设置Want中"bundleName"和"abilityName"字段来指定恢复重启的Ability。 */ static setRestartWant(want: Want) { appRecovery.setRestartWant(want); } } 怎么使用
09-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值