fortran-error-handler
Comprehensive error framework for applications requiring functional and robust error handling, utilising the power of modern object-oriented Fortran.
Science Score: 59.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
✓DOI references
Found 3 DOI reference(s) in README -
✓Academic publication links
Links to: zenodo.org -
✓Committers with academic emails
2 of 3 committers (66.7%) from academic institutions -
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (14.9%) to scientific vocabulary
Keywords
Repository
Comprehensive error framework for applications requiring functional and robust error handling, utilising the power of modern object-oriented Fortran.
Basic Info
Statistics
- Stars: 20
- Watchers: 3
- Forks: 4
- Open Issues: 1
- Releases: 4
Topics
Metadata Files
README.md
Fortran Error Handler
Fortran error handling frameworks are few and far between, and those that do exist often implement only parts of the error handling process, or rely on pre-processors. The goal of this error handling framework is to provide a universal and comprehensive solution for applications requiring functional and robust error handling, utilising the power of modern object-oriented Fortran.
Getting started
There are a few ways to get the Fortran Error Handler into your project. The following have been tested with recent version of the GFortran and Intel Fortran compiler (ifort, not ifx).
fpm - Fortran Package Manager
The simplest way is to use fpm (Fortran Package Manager). You can either directly include the Fortran Error Handler as a dependency in your fpm.toml file:
toml
[dependencies]
feh = { git = "https://github.com/samharrison7/fortran-error-handler" }
Or you can clone the repo and build the library yourself using fpm:
bash
$ git clone https://github.com/samharrison7/fortran-error-handler
$ cd fortran-error-handler
$ fpm build
A static library (e.g. libfeh.a on Linux) and .mod files will be generated in the build directory for you to use. An example executable (using example/example_usage.f90) will also be generated. Running fpm test will run tests (using tests/run_tests.f90) for the framework.
You can also get fpm to install the Fortran Error Handler locally (e.g. to /home/<user>/.local):
bash
$ fpm install
Fpm can easily be installed using Conda: conda install -c conda-forge fpm.
Grab the files
Another simple method is to simple grab a copy of the source files (in src/) and include at the start of your compilation setup. Source files should be compiled in this order: ErrorInstance.f90, ErrorHandler.f90, ErrorCriteria.f90, Result.f90. An example Makefile.example is included, which can be altered according to your compiler and preferences.
Meson
If you use meson, a meson.build file is provided. For example, if you want to build into the buildmeson directory:
bash
$ meson buildmeson
$ ninja -C buildmeson
From meson 0.56, you can use the meson compile command instead of ninja. This will generate the example and test executables, a shared library and module files. You can run the tests directly using meson: meson test -C buildmeson.
By default, the library is built with a debug build type. To build for release (with -O3 optimisations), specify this via the --buildtype=release option:
bash
$ meson buildrelease --buildtype=release
$ ninja -C buildrelease
Installing using meson (meson install) isn't recommended at the moment as .mod files are not installed - see this issue.
CMake
The code can also be compiled using CMake, which similarly generates a library and .mod files, an example executable, and executable of unit tests.
```bash $ mkdir build $ cd build $ cmake .. $ make
To run the unit tests
$ ./test
To run the example
$ ./example ```
Usage
Read the below documentation for example usage, and check out the example directory for ideas of how to incorporate into your project.
Basic structure
The framework consists of two main classes:
- ErrorHandler: Responsible for initiating the error handling environment, queuing and triggering error events, and storing a list of possible error codes and their respective error messages.
- ErrorInstance: An ErrorInstance is an object representing an error, containing an error code, error message, whether the error is critical (should stop the program executing), and a user-defined trace of where the error has come from.
A number of further classes provide added functionality:
- Result: A Result object, though not required to use the framework, is designed as an object to be returned from any procedures that (may) throw an error. An object of
type(Result)contains anerrorscomponent, which is an array of ErrorInstances and is intended to be returned from procedures that normally wouldn't return anything else (i.e., subroutines). To facilitate the returning of data as well as errors from procedures (i.e., functions), a number of separate types extendResult, each one dealing with data of a different rank (dimensionality). In addition to theerrorscomponent, they contain adatacomponent, whose rank is determined by the type name. For example,type(Result0D)is used for scalar data (0D),type(Result1D)is used for data of rank-1 (1D) andtype(Result2D)is used for data of rank-2 (2D). The maximum data rank is currently rank-4 (type(Result4D)). - ErrorCriteria: This class extends the ErrorHandler and defines a number of common "criteria" used for error checking, such as checking whether a number falls between given bounds. Criteria functions expedite the error checking process with intuitive function calls returning pre-defined ErrorInstances.
Quick start guide
Let's create a quick program that asks for a user's input, checks that it passes a number of criteria and if it doesn't, triggers an error.
Firstly, you need to include the appropriate modules to use:
fortran
use ErrorInstanceModule
use ErrorCriteriaModule
use ResultModule
ErrorCriteria extends ErrorHandler and so if we are using the ErrorCriteria class, we don't need to directly use the ErrorHandler. ErrorCriteria can be thought of as the ErrorHandler (thus responsible for storing and triggering errors), but with criteria-checking capabilities. If we're using it, we need to create and initialise an ErrorCriteria instance so that default ErrorInstances are set for different criteria. If we don't want criteria-checking capabilities, we can just create and initialise the ErrorHandler instead.
Let's also initialise an integer to store the user's input into, and a scalar (0D) Result object to store data and errors in:
fortran
type(ErrorCriteria) :: EH ! If criteria-checking not needed, use ErrorHandler instead
integer :: i
type(Result0D) :: r
We first need to initialise the ErrorCriteria (and thus ErrorHandler). This sets a default error with code 1, and a "no error" with code 0, as well as a number of default errors for the criteria (see the ErrorCriteria docs). At the same time, let's specify two custom errors that we might want to trigger at some later point in the code. isCritical determines whether triggering of the error stops the program executing or just prints a warning, and it defaults to true (i.e., triggering an error stops the program).
fortran
call EH%init( &
errors = [ &
ErrorInstance(code=200, message="A custom error message.", isCritical=.false.), &
ErrorInstance(code=300, message="Another custom error message.", isCritical=.true.) &
] &
)
We can also add errors to the ErrorHandler on the fly by using the add procedure: call EH%add(code=200, message="A custom error message.").
Now let's get the user to enter an integer, and specify that it should be between 0 and 10, but not equal to 5:
fortran
write(*,"(a)") "Enter an integer between 0 and 10, but not equal to 5:"
read(*,*) i
We now need to test i meets these criteria, and we can do that using the ErrorCriteria's limit and notEqual methods. We'll do this at the same time as creating the Result object, which stores the data i as well as any errors:
fortran
r = Result( &
data = i, &
errors = [ &
EH%limit(i,0,10), &
EH%notEqual(i,5) &
] &
)
Now we can attempt to trigger any errors that might be present, by using the ErrorHandler's trigger method, which accepts either an error code, an ErrorInstance or an array of ErrorInstances as its parameters. If the criteria check didn't result in any errors, nothing will happen (in reality, the criteria returns an ErrorInstance with code 0 - the default "no error" - which the trigger method ignores).
fortran
call EH%trigger(errors=r%getErrors())
The default ErrorInstances set up by the init procedure for ErrorCriteria all have isCritical set to true, and so if either of these criteria errors are triggered, program execution will be stopped. The default criteria errors can be altered by using the modify procedure - see the ErrorCriteria docs. Finally, let's print the value to the console:
fortran
write(*,"(a,i1)") "Input value is: ", .integer. r
A number of operators, such an .integer. and .real., are available to quickly return the data (which is stored polymorphically) from a Result object as a specific type. If you are uncomfortable using custom operators, then the corresponding procedures r%getDataAsInteger(), r%getDataAsReal(), etc, are also available. See the Result docs for more details.
Let's test it out with a few different integers:
```bash $ Enter an integer between 0 and 10, but not equal to 5: $ 12 $ Error: Value must be between 0 and 10. Given value: 12. $ ERROR STOP 105
$ Enter an integer between 0 and 10, but not equal to 5: $ 5 $ Error: Value must not be equal to 5. Given value: 5. $ ERROR STOP 106
$ Enter an integer between 0 and 10, but not equal to 5: $ 1 $ Input value is: 1 ```
The stop codes 105 and 106 are the default error codes for those particular limit criteria. These codes can be modified using the ErrorCriteria's modifyErrorCriterionCode procedure. See the ErrorCriteria docs.
The framework is designed to work seemlessly in large object-oriented projects, where Result objects can be returned from functions with ErrorInstances that contain a user-defined trace of where the error came from. The goal of such a trace is to provide more useful errors to end users of your application, who might not have access to the source code and thus find standard stack traces containing references to files and line numbers useless. More details can be found in the ErrorInstance docs, and more thorough examples in the examples directory.
Learn more
Explore the documentation for each class to learn how to best use the framework, and browse the examples to get an idea of how to implement the framework into your project:
Caveats and limitations
- Error code must be less than 99999.
- Result objects only support up to rank-4 (4 dimensional) data.
- Limited support for different kinds, due to Fortran's lack of kind polymorphism. In particular, ErrorCriteria only accept 4-byte integers and single precision, double precision and quadruple precision reals, as such:
```fortran integer, parameter :: dp = selectedrealkind(15,307) integer, parameter :: qp = selectedrealkind(33,4931)
integer :: i = 1 real :: r = 1.0 real(dp) :: rdp = 1.0dp real(qp) :: rqp = 1.0qp ```
Owner
- Name: Sam Harrison
- Login: samharrison7
- Kind: user
- Location: Lancaster, UK
- Company: @NERC-CEH
- Website: samharrison.science
- Repositories: 33
- Profile: https://github.com/samharrison7
Research scientist with a passion for programming, design and web development.
CodeMeta (codemeta.json)
{
"@context": "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld",
"@type": "Code",
"author": [
{
"@id": "0000-0001-8491-4720",
"@type": "Person",
"email": "sharrison@ceh.ac.uk",
"name": "Sam Harrison",
"affiliation": "UK Centre for Ecology & Hydrology, Lancaster Environment Centre, Library Avenue, Bailrigg, Lancaster, LA1 4AP, UK"
},
{
"@id": "0000-0003-4489-5363",
"@type": "Person",
"email": "vke@ceh.ac.uk",
"name": "Virginie D Keller",
"affiliation": "UK Centre for Ecology & Hydrology, Maclean Building, Benson Lane, Crowmarsh Gifford, Wallingford, OX10 8BB, UK"
},
{
"@id": "0000-0002-9876-0491",
"@type": "Person",
"email": "rjw@ceh.ac.uk",
"name": "Richard J Williams",
"affiliation": "UK Centre for Ecology & Hydrology, Maclean Building, Benson Lane, Crowmarsh Gifford, Wallingford, OX10 8BB, UK"
},
{
"@id": "0000-0003-3764-5331",
"@type": "Person",
"email": "mihu@ceh.ac.uk",
"name": "Michael Hutchins",
"affiliation": "UK Centre for Ecology & Hydrology, Maclean Building, Benson Lane, Crowmarsh Gifford, Wallingford, OX10 8BB, UK"
},
{
"@id": "0000-0002-3627-851X",
"@type": "Person",
"email": "stlo@ceh.ac.uk",
"name": "Stephen Lofts",
"affiliation": "UK Centre for Ecology & Hydrology, Lancaster Environment Centre, Library Avenue, Bailrigg, Lancaster, LA1 4AP, UK"
}
],
"identifier": "",
"codeRepository": "https://github.com/samharrison7/fortran-error-handler",
"datePublished": "2020-06-05",
"dateModified": "2023-05-31",
"dateCreated": "2020-06-05",
"description": "Comprehensive error framework for applications requiring functional and robust error handling, utilising the power of modern object-oriented Fortran.",
"keywords": "Fortran, error handling",
"license": "MIT",
"title": "Fortran Error Handler",
"version": "v1.0.5"
}
GitHub Events
Total
Last Year
Committers
Last synced: 8 months ago
Top Committers
| Name | Commits | |
|---|---|---|
| Sam Harrison | s****g@g****m | 107 |
| Laurence Kedward | l****d@b****k | 1 |
| Virginie Keller | v****e@c****k | 1 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 7 months ago
All Time
- Total issues: 9
- Total pull requests: 2
- Average time to close issues: 5 months
- Average time to close pull requests: about 4 hours
- Total issue authors: 4
- Total pull request authors: 2
- Average comments per issue: 1.0
- Average comments per pull request: 0.5
- Merged pull requests: 2
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 0
- Pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Issue authors: 0
- Pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
- samharrison7 (6)
- zbeekman (1)
- Beliavsky (1)
- WexeI (1)
Pull Request Authors
- samharrison7 (1)
- LKedward (1)
Top Labels
Issue Labels
Pull Request Labels
Dependencies
- fair-software/howfairis-github-action main composite