Errors in Fortran

In Fortran, error handling is typically done through the use of error codes or status variables. While Fortran doesn’t have a built-in error type like Go, we can simulate similar behavior using integer status codes and custom error messages.

module error_module
  implicit none
  
  ! Define error codes
  integer, parameter :: NO_ERROR = 0
  integer, parameter :: ERR_CANT_WORK_WITH_42 = 1
  integer, parameter :: ERR_OUT_OF_TEA = 2
  integer, parameter :: ERR_POWER = 3

contains
  function get_error_message(error_code) result(message)
    integer, intent(in) :: error_code
    character(len=50) :: message
    
    select case (error_code)
    case (ERR_CANT_WORK_WITH_42)
      message = "can't work with 42"
    case (ERR_OUT_OF_TEA)
      message = "no more tea available"
    case (ERR_POWER)
      message = "can't boil water"
    case default
      message = "unknown error"
    end select
  end function get_error_message
end module error_module

program main
  use error_module
  implicit none
  
  integer :: i, result, error_code
  
  do i = 7, 42, 35
    call f(i, result, error_code)
    if (error_code /= NO_ERROR) then
      print *, "f failed:", get_error_message(error_code)
    else
      print *, "f worked:", result
    end if
  end do
  
  do i = 0, 4
    call make_tea(i, error_code)
    if (error_code /= NO_ERROR) then
      if (error_code == ERR_OUT_OF_TEA) then
        print *, "We should buy new tea!"
      else if (error_code == ERR_POWER) then
        print *, "Now it is dark."
      else
        print *, "unknown error:", get_error_message(error_code)
      end if
      cycle
    end if
    print *, "Tea is ready!"
  end do

contains
  subroutine f(arg, result, error_code)
    integer, intent(in) :: arg
    integer, intent(out) :: result, error_code
    
    if (arg == 42) then
      result = -1
      error_code = ERR_CANT_WORK_WITH_42
    else
      result = arg + 3
      error_code = NO_ERROR
    end if
  end subroutine f
  
  subroutine make_tea(arg, error_code)
    integer, intent(in) :: arg
    integer, intent(out) :: error_code
    
    if (arg == 2) then
      error_code = ERR_OUT_OF_TEA
    else if (arg == 4) then
      error_code = ERR_POWER
    else
      error_code = NO_ERROR
    end if
  end subroutine make_tea
end program main

In this Fortran version:

  1. We define an error_module to encapsulate error-related functionality, similar to Go’s errors package.

  2. Instead of returning multiple values, Fortran subroutines use intent(out) parameters to return results and error codes.

  3. We use integer error codes instead of error objects. A function get_error_message is provided to convert error codes to human-readable messages.

  4. The select case construct is used instead of if-else chains for error handling.

  5. Fortran doesn’t have a built-in way to wrap errors, so we simply return the most specific error code.

  6. The cycle statement in Fortran is equivalent to Go’s continue.

To run this program, save it as errors.f90 and compile it using a Fortran compiler:

$ gfortran errors.f90 -o errors
$ ./errors
f worked: 10
f failed: can't work with 42
Tea is ready!
Tea is ready!
We should buy new tea!
Tea is ready!
Now it is dark.

This Fortran implementation demonstrates error handling patterns similar to those used in the original Go code, adapted to Fortran’s language features and idioms.