diestl
diestl

Reputation: 2058

How to correctly implement error handling?

I am calling a function fit_circle that may or may not call the MESSAGE procedure. fit_circle calls a function poly_fit that may call the MESSAGE procedure, but also occasionaly produces a math error (there is nothing I can do about this).

Is it possible to contruct an error handler that will take care of all of these scenarios without returning to the interactive prompt? I have tried the following:

FUNCTION arb_funct,circular_data
    CATCH, ERROR
    IF ERROR NE 0 THEN BEGIN
        CATCH, /CANCEL
        print, 'An Error Occured'
        return, []
    ENDIF

    circle_fit_result = fit_circle(circular_data)
    return, circle_fit_result
END

However the error handler never triggers. The documentation only seems to mention looking for error handlers defined in procedures.

Upvotes: 0

Views: 1023

Answers (3)

Pi Marillion
Pi Marillion

Reputation: 4674

IDL has three different types of "catchable" errors:

  • "Normal" Errors: These are the most common type of error to handle. They are thrown when message is called. Use catch or on_error to deal with them.
  • IO Errors: These happen when a conversion, disk read, memory, or other "IO" error occurs. Usually, these will also be caught by catch and on_error. When they aren't, use on_ioerror to deal with them.
  • Math Errors: These happen when you divide by 0, do certain math with NaN or infinity, etc. Deal with them using check_math and !except.

Here's an example of using all three in one program:

function arb_funct, circular_data

    ; handle normal errors
    catch, error
    if error ne 0 then begin
        catch, /cancel
        print, 'A normal error occured: ' + !error_state.msg
        return, []
    endif

    ; handle IO errors
    on_ioerror, arb_funct__ioerror
    if 0B then begin
        arb_funct__ioerror:
        print, 'An IO error occured: ' + !error_state.msg
        return, []
    endif

    ; clear math errors from previous routines
    math_err = check_math(/print)
    previous_except = !except
    !except = 0

    ; do stuff
    circle_fit_result = fit_circle(circular_data)

    ; handle math errors
    math_err = check_math()
    !except = previous_except
    if math_err ne 0 then begin
        print, 'A math error occured: ' + strtrim(math_err, 1)
        return, []
    endif

    ; and finally return
    return, circle_fit_result
end

Upvotes: 1

honeste_vivere
honeste_vivere

Reputation: 298

Here is an example of to what I referred:

FUNCTION some_function

;;--------------------------------------------------------------------------
;;  Error handling [put towards beginning of routine]
;;--------------------------------------------------------------------------
CATCH, error_status
IF (error_status NE 0) THEN BEGIN
  ;;  Cancel error handler
  CATCH, /CANCEL
  ;;  Print error message
  PRINT, 'Error index: ', error_status
  PRINT, 'Error message: ', !ERROR_STATE.MSG
  ;;  Define return variable or how to handle error
  ;;    --> I usually use a formatted output consistent with the expected
  ;;        output, but here I will just use 0 for example.
  dumb           = 0  
  ;;  Return defined variable
  RETURN,dumb
ENDIF

;;--------------------------------------------------------------------------
;;  Main body of routine
;;--------------------------------------------------------------------------
blah = 0
; blah
; blah
; blah

;;--------------------------------------------------------------------------
;;  Return to user
;;--------------------------------------------------------------------------

RETURN,return_variable
END

Hope that helps...

Upvotes: 0

mgalloy
mgalloy

Reputation: 2386

Works for me. Here is my example code:

pro mg_error_demo_helper2
  compile_opt strictarr

  a = b
end


pro mg_error_demo_helper1
  compile_opt strictarr

  mg_error_demo_helper2
end


pro mg_error_demo
  compile_opt strictarr
  catch, error
  if (error ne 0L) then begin
    catch, /cancel
    print, 'An error occurred'
    return
  endif

  mg_error_demo_helper1
end

When I run it, I get:

IDL> mg_error_demo
% Compiled module: MG_ERROR_DEMO.
error happened

Upvotes: 1

Related Questions