Combining GetRTError(1) and AbortOnRTE

Hi igoristas,

 

I have some code which tries to talk to hardware

 

    debugOnError = DisableDebugOnError()

    try
        MCC_SelectMultiClamp700B(mccSerial, channel); AbortOnRTE
    catch
        errorCode = GetRTError(1)

        ResetDebugOnError(debugOnError)
        return AMPLIFIER_CONNECTION_MCC_FAILED
    endtry

 

and as that might not always work I'm handling the error case myself.

Now I would like to get rid of the necessary debugOnError disabling/resetting. According to documentation I can use getRTError(1) on the same line as the command to get rid of the debugger fiddling logic (IP7 and above).

 

I've tried with this example

 

Function IAbort()
    Make/FREE/N=0 data
   
    data[0] = NaN
End

Function Dostuff()

    variable errorCode

    try
        IAbort(); errorCode = GetRTError(1); AbortOnRTE
    catch
        print "error"
    endtry
End

but could not get it working as the debugger either still opens or I'm not landing in the catch block.

 

Any ideas what I'm doing wrong?

Since the error is in IAbort(), not DoStuff(), DebugOnError is opening the debugger at the data[0]=NaN line.

If you'd had

Function IAbort()
    Make/FREE/N=0 data
   
    data[0] = NaN; Variable errorCode=GetRTError(1)
    return errorCode
End

then the debugger would not open. But the try/catch in DoStuff() would be pointless since the called routine cleared the error.

I think you're stuck disabling DebugOnError (which was designed to be used only in a development environment) if you are deploying this code to a production environment with DebugOnError turned on.

I'm coming back to this issue as I have more and more code which uses try/catch and AbortOnRTE.

For example one of the functions fetches the latest value from a thread queue

/// @brief Return the newest variable named `varName` from the thread queue
///
/// Return `NaN` if the thread is not running anymore.
///
/// Throws away anything else in the datafolder from the thread queue.
Function TS_GetNewestFromThreadQueue(tgID, varName)
    variable tgID
    string varName

    variable var = NaN
    variable err

    ASSERT_TS(!isEmpty(varName), "varName must not be empty")

    if(IsNaN(tgID))
        return NaN
    endif

    for(;;)
        try
            ClearRTError()
            DFREF dfr = ThreadGroupGetDFR(tgID, TS_GET_REPEAT_TIMEOUT_IN_MS); AbortOnRTE
        catch
            err = GetRTError(1)
            return NaN
        endtry

        if(!DataFolderRefStatus(dfr))
            if(IsFinite(var))
                return var
            elseif(TS_ThreadGroupFinished(tgID))
                return NaN
            else
                continue
            endif
        endif

        NVAR/Z/SDFR=dfr var_thread = $varName

        ASSERT_TS(NVAR_Exists(var_thread), "Expected variable from thread does not exist: " + varName)

        // overwrite old values
        var = var_thread
    endfor

    return var
End

 

And now if I have to debug a problem in the application in unrelated code using DebugOnError, the debugger pops occasionally up on the AbortOnRTE line. This is never a problem as I anticipated that already in this piece of code.
So this makes using DebugOnError a bit annoying.

From my limited Igor Pro understanding I would say that a line with trailing AbortOnRTE should have DebugOnError implicitly disabled for this line only. The whole point of AbortONRTE is that a RTE is expected and the code is designed to handle that.

Thanks for considering,
Thomas