WebDriver.Execute Error Handling #48
Replies: 11 comments 9 replies
-
will take a look and get back to you - thanks! |
Beta Was this translation helpful? Give feedback.
-
@MarkJohnstoneGitHub, the errors handled in the Execute method are related to the web response while the errors in client.Status in the SendRequest method are related to the communication with the local webdriver at 127.0.0.1. |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 It will be a while before get around to testing the errors returned by client status etc. The Excute function is doing a couple of functions with parse the URI and obtaining the response error message. Probably a good idea to place the URI Template parsing into a separate function at least. |
Beta Was this translation helpful? Give feedback.
-
One solution to the "tidiness" problem is to merge Execute and SendRequest, as SendRequest is only called by Execute and no other procedure. How would this work for both of you? Friend Function Execute(driverCommand As Variant, Optional parameters As Dictionary = Nothing, Optional ByVal raise As Boolean = True) As Dictionary
Dim cmdMethod As String
Dim cmdPath As String
Dim cmdArgs As New Dictionary
Dim parmKey As Variant
Dim response As Dictionary
Dim client As New MSXML2.ServerXMLHTTP60
Dim jc As New WebJsonConverter
cmdMethod = driverCommand(0)
cmdPath = driverCommand(1)
If parameters Is Nothing Then
Set parameters = New Dictionary
End If
'Set session id
If Not parameters.Exists("sessionId") Then
parameters.Add "sessionId", sessionId_
End If
For Each parmKey In parameters.keys
If InStr(cmdPath, "$" & parmKey) > 0 Then 'path parameter
cmdPath = Replace(cmdPath, "$" & parmKey, parameters(parmKey))
Else 'non-path parameter
cmdArgs.Add parmKey, parameters(parmKey)
End If
Next parmKey
'there are commands that don't require sessionId in path: tCMD.CMD_STATUS, tCMD.CMD_NEW_SESSION, tCMD.CMD_GET_ALL_SESSIONS, tCMD.CMD_SHUTDOWN
If cmdArgs.Exists("sessionId") Then cmdArgs.Remove "sessionId"
'Send request to selenium server
client.Open cmdMethod, driverUrl_ & cmdPath
'set receiveTimeout to infinite to accommodate longer than 30 sec (default) pageloads
client.setTimeouts 0, 60000, 30000, 0
If cmdMethod = "POST" Or cmdMethod = "PUT" Then
client.setRequestHeader "Content-Type", "application/json; charset=utf-8"
client.setRequestHeader "Cache-Control", "no-cache"
client.send jc.ConvertToJson(cmdArgs) '
Else
client.send
End If
Do While client.readyState < 4
DoEvents
Loop
Set response = jc.ParseJson(client.responseText)
If raise And IsResponseError(response) Then 'raise error if occurs
Debug.Print GetResponseErrorMessage(response)
Err.raise client.status, "WebDriver", GetResponseErrorMessage(response)
End If
Set Execute = response 'Pass the response dictionary object - let caller parse info based on context, including error
End Function |
Beta Was this translation helpful? Give feedback.
-
+1 to merge the two methods Your mix of "If [...] IsResponseError(response) Then [...] Err.raise client.status" is actually a bug. When SeleniumVBA for example opens a web page, if that page is not found, client.Status will still be "200 Ok" while "response" ("response" only) will contain the wanted "404 - no such element" error. We could just rename lHttpStatus to lRemoteHttpStatus to avoid confusion... |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9, I think I understand what you are saying, and it makes sense to me, but I cannot replicate. When using the merged Execute that I posted above, every error that I have generated (so far) the client.status equals one of the remote response codes (400-500). I'm only getting 200 when there is no error. What am I missing? Can you provide an example? Thanks! |
Beta Was this translation helpful? Give feedback.
-
Ahhh I've had a better look and I've to apologize! your solution @GCuser99 is actually perfect and the best one for me! The thing that misled me was the fact that the following line passes with a client.status = 200: |
Beta Was this translation helpful? Give feedback.
-
Yes, very interesting - browser returns 404 but driver returns 200.... head scratcher... |
Beta Was this translation helpful? Give feedback.
-
I guess that result is because Google redirects to its own 404 page. If you try NavigateTo "https://www.gooooooogle.com" .... then driver returns 500 unknown error |
Beta Was this translation helpful? Give feedback.
-
Another thing this discussion exposes - I looked a little closer as to why the error messages seem to have a bunch of escaped characters... I think we need to make this modification: Private Function GetResponseErrorMessage(resp As Dictionary) As String
'Dim jc As New WebJsonConverter 'old way
GetResponseErrorMessage = vbNullString
If TypeName(resp("value")) = "Dictionary" Then
If resp("value").Exists("error") Then
'GetResponseErrorMessage = jc.ConvertToJson(resp("value")("message"), 4) 'old way
GetResponseErrorMessage = resp("value")("message") 'new way
End If
End If
End Function |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 "the errors handled in the Execute method are related to the web response while the errors in client.Status in the SendRequest method are related to the communication with the local webdriver at 127.0.0.1." I did some brief testing what was returned from client and response for the NavigateTo with an invalid URL using Chrome. Using GetErrorMessage post above by @GCuser99 and a GetErrorStatus(response) extracted from the Excute function. For testing I created a separate class for handling the response for testing WebDriverResponse.cls. Possibly handy if fleshed out to search the WebDriverResponse dictionary for other WebDriver commands. I might look into that later. Invalid URL NavigateTo From
|
Beta Was this translation helpful? Give feedback.
-
It appears could move the error handling in WebDriver.Execute to WebDriver.SendRequest as have access to the HRESULT/HTTP status code in WebDriver.SendRequest . That would tidy up the Execute function.
HTTP status codes
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms767681(v=vs.85)
https://www.w3.org/TR/webdriver/#dfn-error-code
In WebDriver.SendRequest
'Or maybe. Note if status codes >= 400 are only errors then change accordingly
Select Case client.Status
Case 200 'OK
Case Else
Err.raise client.Status, "WebDriver", client.responseText
End Select
If client.responseText isn't anappropriate errror message then maybe the IsResponseError(response) and GetResponseErrorMessage(response). Maybe in the calling command eg NavigateTo could Raise a specific error message from the response.
Beta Was this translation helpful? Give feedback.
All reactions