flibs/m_vfile(n) 1.0 "flibs"
flibs/m_vfile - Manage exceptions
TABLE OF CONTENTS
SYNOPSIS
DESCRIPTION
OVERVIEW
Simple use-case
Controlling the execution
Controlling output
Pseudo-catch
ROUTINES
TODO
COPYRIGHT
Provides services to generate different levels of exceptions
and display the message of the exception.
Five levels of exceptions can be generated, from the lowest
to the highest level :
- information, warning : just print a message and continue
- error, fatal_error and failure : prints a message and stop the execution
Suppose that one would like to compute the square root of one
real value. The "compute_sqrt" function takes one positive real argument,
and if the argument is negative, one cannot compute the square root so
that one would generate an error. In the following example, extracted from the
unit tests included in the project, one uses the static method "exception_raiseError"
to display a user-friendly message and stop the execution of the program
|
function compute_sqrt ( value ) result ( root )
use m_exception
implicit none
real, intent(in) :: value
real :: root
if ( value < 0. ) then
call exception_raiseError ( "Value is negative in compute_sqrt" )
else
root = sqrt ( value )
endif
end function compute_sqrt
real :: root
root = compute_sqrt ( -1. )
|
In the previous example, the standard output is written so that the
following message appears on screen.
|
Error.
Message: Value is negative in compute_sqrt
|
The client code can control the behaviour of the component each time
an exception is raised.
The default behaviour is to stop the execution. This can be modified
by calling "exception_setstoponerror" in order to continue the execution,
even if error, fatal error or failure exceptions are raised.
In the following example, the static method "exception_setstoponerror" is
called so that an error does not interrupt the execution.
|
call exception_setstoponerror ( .false. )
call exception_raiseError ( "There is an error, but the execution will continue." )
|
The default behaviour is to write messages onto the standard output
each time an exception is raised.
This can be modified in two ways.
- the first possibility is to disable the writing of the messages
with "exception_logactive". This feature might be useful in the case
where a component has known bugs but generates lots of unwanted
exceptions messages.
- the second possibility is to connect the component to an existing unit
with "exception_setlogunit", so that the messages are written
on the given logical unit number.
This allows for example to write on an existing log file, may be the log
file manage by the m_logger component included in the project.
In the following example, the client code first disables all output,
set "stoponerror" to false and generates an error which is not displayed
and does not interrupt the execution.
|
call exception_setstoponerror ( .false. )
call exception_logactive ( .false. )
call exception_raiseError ( "This message will not be displayed and the execution will continue." )
call exception_logactive ( .true. )
call exception_raiseError ( "This message WILL be displayed and the execution will continue." )
|
In the following example, the client code connect the m_exception component to
an existing unit so that the exception messages are written onto a client log file.
|
log_fileunit = 12
call exception_setstoponerror ( .false. )
open ( log_fileunit , FILE= "log_file.log" )
call exception_setlogunit ( log_fileunit )
call exception_raiseError ( "This message will be written in log_file.log and the execution will continue." )
call exception_setlogunit ( 0 )
call exception_raiseError ( "This message will be written on standard output and the execution will continue." )
close ( log_fileunit )
|
In the following example, the client code connects the m_exception component to
the logfile manage by m_logger. This way, the exception messages are collected in the
unique log file of the client code.
|
call log_startup ( "log_file.log" , append=.true. )
call log_cget ( "logfileunit" , log_fileunit )
call exception_setstoponerror ( .false. )
call exception_setlogunit ( log_fileunit )
call exception_raiseError ( "This message will be written in log_file.log and the execution will continue." )
call log_shutdown ()
|
The client code can use a pseudo-catch system which provides
a simple way to manage exceptions which are raised at a lower
level in the call stack. This allows to provide special
treatments when exceptions are generated, without modifiying
all lower level subroutines/function, but just by inserting
exception management when needed.
Suppose that you have a subroutine which source code is the following.
|
subroutine yoursubroutine ()
use m_exception, only : exception_raiseFatalError
implicit none
[...]
call exception_raiseFatalError ( "Wrong blabla in yoursubroutine" )
[...]
end subroutine yoursubroutine
|
When calling the subroutine "yoursubroutine", one may wonder if exceptions
have been generated so that these errors may be processed, or not.
One can use the "exception_catch" service to compute the status
of one subroutine and manage that status.
|
use m_exception, only : exception_catch, &
EXCEPTION_INFORMATION, &
EXCEPTION_WARNING &
EXCEPTION_ERROR &
EXCEPTION_FATAL_ERROR &
EXCEPTION_FAILURE
integer :: status
call exception_catch ( yoursubroutine , status )
select case ( status )
case ( EXCEPTION_INFORMATION )
write(6,*) "Information"
case ( EXCEPTION_WARNING )
write(6,*) "Warning"
case ( EXCEPTION_ERROR , EXCEPTION_FATAL_ERROR , EXCEPTION_FAILURE )
write(6,*) "Fatal error"
case default
write(6,*) "No problem, continue."
end select
|
- exception_raiseFatalError ( message )
-
- character(len=*), intent(in) :: message
-
Generates a fatal error message and stops the execution.
- exception_raiseError ( message )
-
- character(len=*), intent(in) :: message
-
Generates an error message and stops the execution.
- exception_raiseWarning ( message )
-
- character(len=*), intent(in) :: message
-
Generates a warning message.
- exception_raiseInformation ( message )
-
- character(len=*), intent(in) :: message
-
Generates an information message.
- exception_raiseFailure ( message )
-
- character(len=*), intent(in) :: message
-
Generates a failure message and stops the execution
- exception_setstoponerror ( stoponerror )
-
- logical, intent(in) :: message
-
If stoponerror is true, then when an error, a fatal_error or a failure
is generated, then stop the execution.
If stoponerror is false, then the same exceptions do not stop the
execution.
- exception_initcounter ( )
-
- logical, intent(in) :: message
-
Reset to 0 all the exceptions counters.
- exception_getcounter ( )
-
- integer, dimension(1:EXCEPTION_SIZE), intent(out) :: counter
-
Returns an array of size EXCEPTION_SIZE indicating the number
of exceptions of each type. The value of excepcounters ( iexcept )
is the total number of exceptions of type #iexcept generated since the begining
of the execution. The possible values for iexcept are the following.
- counter ( EXCEPTION_INFORMATION ) : total number of information exceptions raised
- counter ( EXCEPTION_WARNING ) : total number of warning exceptions raised
- counter ( EXCEPTION_ERROR ) : total number of error exceptions raised
- counter ( EXCEPTION_FATAL_ERROR ) : total number of fatal error exceptions raised
- counter ( EXCEPTION_FAILURE ) : total number of failure exceptions raised
- exception_report ( )
-
Writes on the current exception unit number a report
which details the number of exceptions of all types
since the begining of the execution or the last reset of
all counters.
- exception_setlogunit ( unitnumber )
-
- integer, intent(in) :: unitnumber
-
Set the unit number onto which the messages are output.
If the unitnumber is negative or 0, the messages are written
to the standard output (unit *).
Note : a unitnumber equals to 6 is generally the standard output,
but this may depend on the fortran compiler.
- exception_getlogunit ( ) result ( logunit )
-
- integer :: logunit
-
Returns the positive unit number onto which the messages are output,
if enabled or a negative integer if the feature is disabled.
- exception_logactive ( bool )
-
- logical, intent(in) :: bool
-
If the boolean argument bool is true, enable the logging
of the exceptions messages.
If the boolean argument bool is false, disable the logging
of the exceptions messages.
- exception_islogactive ( ) result ( islogactive )
-
- logical :: islogactive
-
Returns .true. if the current exception messages are written,
either on standard output or into a log file.
- exception_catch ( callback , status ) result ( islogactive )
-
- integer, intent(out) :: status
-
|
interface interfacecallback
subroutine callback ()
end subroutine callback
end interface interfacecallback
|
Calls the given subroutine callback and set status as an
the integer associated with last exception, higher level, code or 0 if no exception
was raised.
Caution : the internal algorithm is based on the exception counters,
which implies that any call to exception_initcounter in the client
code can result in a wrong status.
Copyright © 2008 Michael Baudin michael.baudin@gmail.com
Copyright © 2008 Arjen Markus arjenmarkus@sourceforge.net