@@ -16,53 +16,96 @@ module m_error_v
1616 ! ! Code that indicates no error
1717
1818 type, public :: ErrorV
19- ! ! Error value
19+ ! ! Error value
2020
2121 integer :: code = 1
2222 ! ! Error code
2323
24- character (len= 128 ) :: message = " "
24+ character (len= :), allocatable :: message
2525 ! ! Error message
2626 ! TODO: think about making the message allocatable to handle long messages
2727
2828 ! TODO: think about adding idea of critical
2929 ! (means you can stop but also unwind errors and traceback along the way)
3030
3131 ! TODO: think about adding trace (might be simpler than compiling with traceback)
32- ! type(ErrorV), allocatable, dimension(:) :: causes
32+ ! class(ErrorV), allocatable :: cause
33+ type (ErrorV), pointer :: cause = > null ()
3334
3435 contains
3536
3637 private
3738
3839 procedure , public :: build
3940 procedure , public :: finalise
41+ ! procedure, public :: get_error_message
4042 final :: finalise_auto
4143 ! get_res sort of not needed (?)
4244 ! get_err sort of not needed (?)
4345
4446 end type ErrorV
4547
4648 interface ErrorV
47- ! ! Constructor interface - see build (TODO: figure out cross-ref syntax) for details
49+ ! ! Constructor interface - see build (TODO: figure out cross-ref syntax) for details
4850 module procedure :: constructor
4951 end interface ErrorV
5052
5153contains
5254
53- function constructor (code , message ) result(self)
55+ ! pure recursive function get_error_message(self) result(full_msg)
56+ !
57+ ! class(ErrorV), target, intent(in) :: self
58+ !
59+ ! character(len=:), allocatable :: full_msg
60+ ! character(len=:), allocatable :: cause_msg
61+ !
62+ ! full_msg = self%message
63+ ! if (associated(self%cause)) then
64+ ! cause_msg = self%cause%get_error_message()
65+ ! full_msg = trim(full_msg) // ' Previous error: ' // trim(cause_msg)
66+ ! end if
67+ !
68+ ! end function
69+ ! function get_error_message(self) result(full_msg)
70+ !
71+ ! class(ErrorV), target, intent(in) :: self
72+ ! class(ErrorV), pointer :: p_errorv
73+ !
74+ ! character(len=:), allocatable :: full_msg
75+ !
76+ ! full_msg = ""
77+ !
78+ ! if (allocated(self%message)) full_msg = trim(self%message)
79+ ! p_errorv => self
80+ !
81+ ! do while (associated(p_errorv))
82+ !
83+ ! if(len(full_msg)>0)then
84+ ! full_msg = trim(full_msg) // " --> Cause: " // p_errorv % message
85+ ! else
86+ ! full_msg = p_errorv % message
87+ ! end if
88+ !
89+ ! p_errorv => p_errorv % cause
90+ !
91+ ! end do
92+ !
93+ ! end function
94+
95+ function constructor (code , message , cause ) result(self)
5496 ! ! Constructor - see build (TODO: figure out cross-ref syntax) for details
5597
5698 integer , intent (in ) :: code
5799 character (len=* ), optional , intent (in ) :: message
100+ type (ErrorV), target , optional , intent (in ) :: cause
58101
59102 type (ErrorV) :: self
60103
61- call self % build(code, message)
104+ call self % build(code, message, cause )
62105
63106 end function constructor
64107
65- subroutine build (self , code , message )
108+ subroutine build (self , code , message , cause )
66109 ! ! Build instance
67110
68111 class(ErrorV), intent (inout ) :: self
@@ -75,10 +118,25 @@ subroutine build(self, code, message)
75118
76119 character (len=* ), optional , intent (in ) :: message
77120 ! ! Error message
121+ type (ErrorV), target , optional , intent (in ) :: cause
78122
79123 self % code = code
80- if (present (message)) then
81- self % message = message
124+
125+ if (present (cause)) then
126+ ! self % cause => cause
127+ ! allocate(self % cause)
128+ ! call self%cause%build(cause%code, cause%message, cause%cause)
129+ ! self%cause = cause
130+ if (present (message)) then
131+ self % message = trim (message) // " --> Cause: " // cause % message
132+ else
133+ self % message = " --> Cause: " // cause % message
134+ end if
135+
136+ else
137+ if (present (message)) then
138+ self % message = trim (message)
139+ end if
82140 end if
83141
84142 end subroutine build
@@ -91,7 +149,13 @@ subroutine finalise(self)
91149
92150 ! If we make message allocatable, deallocate here
93151 self % code = 1
94- self % message = " "
152+ if (allocated (self% message)) deallocate (self% message)
153+ ! MZ when the object is finalized or goes out of scope, its pointer components are destroyed.
154+ ! Hopefully no shared ownership??
155+ if (associated (self% cause))then
156+ deallocate (self% cause)
157+ nullify(self% cause)
158+ end if
95159
96160 end subroutine finalise
97161
0 commit comments