server-client-python icon indicating copy to clipboard operation
server-client-python copied to clipboard

Fix unhelpful error message when connecting to server fails: 'Invalid Version: Unknown'

Open genehynson opened this issue 1 year ago • 0 comments

Describe the bug

When initializing the Tableau Server client it's possible to encounter the error message Invalid Version: Unknown which is rather confusing and does not provide enough context to debug the real issue. This occurs whenever the Tableau server name provided does not resolve to a Tableau Server (e.g. perhaps because of an SSO wall). However, the error message incorrectly implies that there is some sort of issue during the negotiation of API versions, which is very confusing.

Our usage:

import tableauserverclient as tsc
...
self._server = tsc.Server(server_name)
self._server.add_http_options({"verify": verify_ssl})
self._server.use_server_version()
self._server.auth.sign_in(auth)

This error is raised because:

  • use_server_version() invokes _determine_highest_version() which invokes self.server_info.get().rest_api_version
  • ServerInfo.get() makes an unauthenticated request to the provided url to attempt to fetch the server version info. The response is received from the server but it is not the payload expected by the client (it's likely an html webpage) but no error is raised.
  • The bad response payload is then parsed by ServerInfoItem.from_response() where an error is raised.
  • The error is caught and silenced, with response cls("Unknown", "Unknown", "Unknown") returned.
  • This results in Server.version to be set to "Unknown" here.
  • So when the client attempts authenticate with the Tableau Server, the @api(...) decorator is invoked which invokes Server.check_at_least_version() here.
  • And initializing Version("Unknown") causes the unhandled error Invalid Version: Unknown to be raised.

I think that the invalid response payload should raise an error with a message like "Invalid server info response received from provided Tableau server url" instead of silencing this issue.

Versions Details of your environment, including:

  • Tableau Server version (or note if using Tableau Online): 3.23
  • Python version: 3.11
  • TSC library version: v0.32

To Reproduce Provide a url that does not resolve to a Tableau server to the client.

import tableauserverclient as tsc
_server = tsc.Server("https://getmontecarlo.com")
_server.use_server_version()
# random jwt of no significance
_server.auth.sign_in(tsc.JWTAuth(jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"))

Results

Unhelpful error is raised: InvalidVersion: Invalid version: 'Unknown'

Traceback (most recent call last):
  File "/Users/ghynson/Desktop/tableau-test/main.py", line 4, in <module>
    _server.auth.sign_in(tsc.JWTAuth(jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"))
  File "/Users/ghynson/.pyenv/versions/dc11/lib/python3.11/site-packages/tableauserverclient/server/endpoint/endpoint.py", line 253, in wrapper
    self.parent_srv.assert_at_least_version(version, self.__class__.__name__)
  File "/Users/ghynson/.pyenv/versions/dc11/lib/python3.11/site-packages/tableauserverclient/server/server.py", line 194, in assert_at_least_version
    if not self.check_at_least_version(comparison):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ghynson/.pyenv/versions/dc11/lib/python3.11/site-packages/tableauserverclient/server/server.py", line 189, in check_at_least_version
    server_version = Version(self.version or "2.4")
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ghynson/.pyenv/versions/dc11/lib/python3.11/site-packages/packaging/version.py", line 200, in __init__
    raise InvalidVersion(f"Invalid version: '{version}'")
packaging.version.InvalidVersion: Invalid version: 'Unknown'

genehynson avatar Aug 28 '24 18:08 genehynson