设计思路
- 集中捕获:在主程序或者关键调用点设置统一的错误捕获机制,确保所有模块抛出的错误都能被捕获。
- 分类处理:根据错误类型进行分类,例如将语法错误、运行时错误等分开处理,以便采取不同的应对策略。
- 日志记录:记录错误发生的详细信息,包括错误类型、错误发生的模块、时间等,便于后续追踪和分析。
- 错误追踪:通过某种标识(如错误编号)和日志记录,能够快速定位错误发生的具体位置和原因。
关键数据结构
- 错误类型枚举:定义一个枚举类型来表示不同的错误类型。
integer, parameter :: ERROR_TYPE_SYNTAX = 1
integer, parameter :: ERROR_TYPE_RUNTIME = 2
! 其他错误类型可以继续添加
- 错误信息结构体:用于存储错误的详细信息。
type ErrorInfo
integer :: error_type
character(len=256) :: error_message
character(len=128) :: module_name
integer :: line_number
real :: timestamp
end type ErrorInfo
错误处理流程
- 错误抛出:各个模块在发生错误时,构造
ErrorInfo
结构体并抛出错误。
- 错误捕获:在主程序或关键调用点,使用
try - catch
机制捕获错误。
- 分类处理:根据
error_type
字段对错误进行分类处理。
- 日志记录:将错误信息记录到日志文件中。
代码片段
- 模块内错误抛出示例
module SomeModule
implicit none
contains
subroutine SomeSubroutine()
type(ErrorInfo) :: err
! 模拟运行时错误
if (.false.) then
err%error_type = ERROR_TYPE_RUNTIME
err%error_message = 'Runtime error occurred'
err%module_name = 'SomeModule'
err%line_number = __LINE__
call system_clock(count=err%timestamp)
error stop 'Error in SomeSubroutine'
end if
end subroutine SomeSubroutine
end module SomeModule
- 主程序中的错误捕获与处理
program MainProgram
use SomeModule
implicit none
type(ErrorInfo) :: caught_err
integer :: ierr
character(len=256) :: log_message
try
call SomeSubroutine()
catch
! 捕获错误并填充错误信息
caught_err%error_type = ERROR_TYPE_RUNTIME
caught_err%error_message = 'Caught error in MainProgram'
caught_err%module_name = 'MainProgram'
caught_err%line_number = __LINE__
call system_clock(count=caught_err%timestamp)
! 分类处理错误
select case (caught_err%error_type)
case (ERROR_TYPE_SYNTAX)
! 处理语法错误
write(*,*) 'Syntax error:', caught_err%error_message
case (ERROR_TYPE_RUNTIME)
! 处理运行时错误
write(*,*) 'Runtime error:', caught_err%error_message
case default
write(*,*) 'Unknown error:', caught_err%error_message
end select
! 日志记录
write(log_message, fmt='(A, I0, A, A, A, I0, A, F10.3)') &
'[' , caught_err%timestamp, '] ', &
caught_err%module_name, ' (line ', caught_err%line_number, '): ', &
caught_err%error_message
open(unit=10, file='error_log.txt', position='append', iostat=ierr)
if (ierr == 0) then
write(10,*) log_message
close(10)
else
write(*,*) 'Failed to write to error log'
end if
end try
end program MainProgram