Jump to content

How can I check if an object's property exists?


Tippex
 Share

Recommended Posts

I'm having a problem with _IEBodyReadText() which is a function from the IE.au3 UDF include.

Quote

    Version:  T3.0-1
    Last Update: 13/06/02
    Requirements: AutoIt3 3.3.9 or higher

    Update History:
    ===================================================
    T3.0-2 14/8/19

My problem is that randomly it will crash my script with:

Return SetError($_IESTATUS_Success, 0, $oObject.document.body.innerText)
Return SetError($_IESTATUS_Success, 0, $oObject.document.body^ ERROR

I don't know why the error isn't caught by __IEErrorHandlerRegister but looking at this function, I can see that there is a check done by IsObj($oObject) to ensure that the object "$oObject" exists but no check that it contains the property "innerText"

; #FUNCTION# ====================================================================================================================
; Author ........: Dale Hohm
; ===============================================================================================================================
Func _IEBodyReadText(ByRef $oObject)
    If Not IsObj($oObject) Then
        __IEConsoleWriteError("Error", "_IEBodyReadText", "$_IESTATUS_InvalidDataType")
        Return SetError($_IESTATUS_InvalidDataType, 1, 0)
    EndIf
    If Not __IEIsObjType($oObject, "browserdom") Then
        __IEConsoleWriteError("Error", "_IEBodyReadText", "$_IESTATUS_InvalidObjectType", "Expected document element")
        Return SetError($_IESTATUS_InvalidObjectType, 1, 0)
    EndIf
    ;
    Return SetError($_IESTATUS_Success, 0, $oObject.document.body.innerText)
EndFunc   ;==>_IEBodyReadText

I'm struggling to find out how to test if "$oObject.document.body.innerText" exists before allowing the following Return statement to reference it with the assumption that it does exist (crashing my script when it doesn't).

Any ideas please?

Link to comment
Share on other sites

Hi @Tippex.

One way is to use Execute to call _IEBodyReadText like so:

Local $sText = Execute("_IEBodyReadText($oIE)")

I would also suggest including your script if more advice is needed.

Link to comment
Share on other sites

1 hour ago, Tippex said:

I don't know why the error isn't caught by __IEErrorHandlerRegister

Couldn't find a place where this function gets called in the UDF.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Thank you.

Error handling appears to be switched on and off as needed in some IE.au3 functions but missing for this particular function.

I think the necessary fix to stabilise this function may be something like:

Func _IEBodyReadText(ByRef $oObject)
    If Not IsObj($oObject) Then
        __IEConsoleWriteError("Error", "_IEBodyReadText", "$_IESTATUS_InvalidDataType")
        Return SetError($_IESTATUS_InvalidDataType, 1, 0)
    EndIf
    If Not __IEIsObjType($oObject, "browserdom") Then
        __IEConsoleWriteError("Error", "_IEBodyReadText", "$_IESTATUS_InvalidObjectType", "Expected document element")
        Return SetError($_IESTATUS_InvalidObjectType, 1, 0)
    EndIf

    ;------------------------------------------------------------------------------------------
    ; Check to verify that the document body object has an innerText property, if not, skip trying to return its contents
    ;
    ; Setup internal error handler to Trap COM errors, turn off error notification,
    ;     check object property validity, set a flag and reset error handler and notification
    ;
    Local $bIsInnerText = True
    ; Trap COM errors and turn off error notification
    $bStatus = __IEInternalErrorHandlerRegister()
    If Not $bStatus Then __IEConsoleWriteError("Warning", "_IEBodyReadText", _
            "Cannot register internal error handler, cannot trap COM errors", _
            "Use _IEErrorHandlerRegister() to register a user error handler")
    ; Turn off error notification for internal processing
    $iNotifyStatus = _IEErrorNotify() ; save current error notify status
    _IEErrorNotify(False)

    ; Check conditions to verify that the object is a browser
    If $bIsInnerText Then
        $sTmp = $oObject.document.body.innerText ; Is .innerText a valid property?
        If @error Then $bIsInnerText = False
    EndIf

    ; restore error notify
    _IEErrorNotify($iNotifyStatus) ; restore notification status
    __IEInternalErrorHandlerDeRegister()
    ;------------------------------------------------------------------------------------------

    If $bIsInnerText Then   
        Return SetError($_IESTATUS_Success, 0, $oObject.document.body.innerText)
    Else
        __IEConsoleWriteError("Error", "_IEBodyReadText", "$_IESTATUS_InvalidObjectType", "Expected innerText element")
        Return SetError($_IESTATUS_InvalidObjectType, 1, 0)     
    EndIf
        
EndFunc   ;==>_IEBodyReadText

 

May I ask why calling it with an execute catches errors better please?

Thanks

 

 

 

 

 

 

Edited by Tippex
Link to comment
Share on other sites

3 minutes ago, junkew said:

Out of interest but under which circumstance there would not be a document.body.innertext property available? 
As far as I know IE has this property allways.

when loading for example. But i am sure there exists rare circumstances where this problem would occur.

Link to comment
Share on other sites

  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...