Initializing help system before first use

I/O error handling

Mosel's default behaviour on encountering an error is to output an error message and exit from model execution. If a model is embedded into an application this behaviour might not always be desirable, particularly in the case of I/O errors. Data filenames (and contents) most often are changed at runtime and they are therefore relatively more error-prone than invariable parts of the application.

The following modified extract of the 'transport' example from Section A transport example shows how to implement custom I/O error handling in a Mosel model. To override the default error handling, this example uses getparam and setparam to access and change the settings of several Mosel parameters:

ioctrl
Enable/disable user I/O handling. If disabled (default), the model stops when an I/O error has occurred.
readcnt
Enable/disable counting of entries per label in 'initializations' blocks. Needs to be enabled when using function getreadcnt.
nbread
Number of items recognized by the last read procedure or read in by the last 'initializations' block.
iostatus
Status of the last I/O operation. A non-zero value indicates an error.
workdir
The current working directory of the model. Data files are searched for relative to the model's working directory—incorrect paths are quite a common source of I/O errors.

Furthermore, we use the function getfstat provided by the module mmsystem to check whether the data file we are about to access exists and is of a suitable type (regular file).

Model file readdataerr.mos:

model "I/O error handling"
 uses "mmsystem"

 declarations
  REGION: set of string                 ! Set of customer regions
  PLANT: set of string                  ! Set of plants
  DEMAND: array(REGION) of real         ! Demand at regions
  TRANSCAP,DISTANCE: dynamic array(PLANT,REGION) of real   ! Route data
  FUELCOST: real                        ! Fuel cost per unit distance
 end-declarations

 DATAFILE:= 'transprt.dat'

! Check whether the file we want to access exists
 if bittest(getfstat(DATAFILE),SYS_TYP)<>SYS_REG then
  writeln("File '", DATAFILE, "' does not exist or is not a regular file")
  exit(1)
 end-if

 setparam("ioctrl", true)               ! Application handles I/O errors
 setparam("readcnt", true)              ! Enable per label counting

 initializations from DATAFILE
  DEMAND
  [DISTANCE,TRANSCAP] as 'ROUTE'
  FUELCOST
 end-initializations

 if getparam("iostatus") <>0 then       ! Something has gone wrong in last I/O
  writeln("I/O error reading file '", DATAFILE, "'.")
                                        ! Display the working directory
  writeln("Working directory: ", getparam("workdir"))
                                        ! Display total entries read
  writeln("Total number of entries read: ", getparam("nbread"))
                                        ! Check no. of entries read per label
  forall(s in ["DEMAND","ROUTE","FUELCOST"])
   if getreadcnt(s)=0 then
    writeln("No entries read for label '", s, "'.")
   else
    writeln(getreadcnt(s), " entries read for label '", s, "'.")
   end-if
 end-if

 setparam("ioctrl", false)              ! Revert to default I/O handling
 setparam("readcnt", false)

end-model

We have purposely introduced a mistake (the correct label for the route data is 'ROUTES') and running this model therefore displays an error message produced by Mosel, and also the following output produced by our own error reporting.

I/O error reading file 'transprt.dat':
Mosel: E-33: Initialization from file `transprt.dat' failed for: `ROUTE'.
Working directory: c:/xpress/examples/mosel/UG/A3
Total number of entries read: 6
5 entries read for label 'DEMAND'.
No entries read for label 'ROUTE'.
1 entries read for label 'FUELCOST'.

Given that this model implements its own error handling, we might want to entirely disable the display of error messages from Mosel by redirecting the error stream to 'null:', that is, surrounding the 'initializations' block with these lines:

 fopen("null:", F_ERROR)                ! Optional: Disable error stream
 ...                                    ! Initialization of data from file
 fclose(F_ERROR)                        ! Stop error redirection

Important: always remember to terminate the error stream redirection by closing the selected output file, otherwise you will no longer see any error output from Mosel from the rest of the model.

Instead of completely ignoring the error messages produced by Mosel, we might also choose to save them to a file in order to inspect or display them later on. This may be a physical (text) file, or for example, a text object directly in the model as shown in this code extract:

 public declarations
  errtxt: text                          ! Text used as file to log errors
 end-declarations

 fopen("text:errtxt", F_ERROR)          ! Redirect error stream to a file (text)
 ...                                    ! Initialization of data from file
 fclose(F_ERROR)                        ! Stop error redirection

 if getparam("iostatus") <>0 then       ! Something has gone wrong in last I/O
  writeln("I/O error reading file '", DATAFILE, "': ", errtxt)
  ...
 end-if

In the error redirection we have used 'null:' and 'text:', these two are I/O drivers which are explained with some more detail in Section List of I/O drivers. Concerning the type 'text' please see the discussion in Section text vs. string.

Note: Certain Mosel modules and also the Mosel Libraries have additional functionality for error handling, such as debug settings for ODBC (see the chapter 'mmodbc' of the Mosel Language Reference for details), or the redirection of Mosel streams from applications (as in Sections Redirecting the Mosel output or Redirecting the Mosel output) of other models (see the example of Section Exchanging data between models).


© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.