Godot Version
4.4.1
Question
I am updating my music app to be able to request the latest public version from the Github repo so the user can see if there has been any updates, I have managed to get it working but as this is my first real dive into HTTP/Internet things in programming I was wondering if there are any good practises / must-knows when it comes to handling errors / exceptions?
Currently this is my code, I have tried to handle errors by reporting all as failed opposed to trying to resolve it
I have the awaits to avoid checking the same things every frame unnecessarily:
func attempt_repo_connection() -> bool:
## 'cli_print_callable' prints something to the CLI present in the app.
cli_print_callable.call("SYS: Attempting to connect to Github API.")
repo_http_client.connect_to_host("https://api.github.com")
var continue_attempt : bool = true
var attempt_start_time : int = int(Time.get_unix_time_from_system())
while continue_attempt:
await get_tree().create_timer(0.25).timeout
repo_http_client.poll()
await get_tree().create_timer(0.25).timeout
match repo_http_client.get_status():
HTTPClient.Status.STATUS_CONNECTED:
repo_connection_succesfull = true
cli_print_callable.call("SYS_ALERT: Succesfully connected to GitHub API.")
return true
HTTPClient.Status.STATUS_RESOLVING, HTTPClient.Status.STATUS_CONNECTING:
## If it has taken over 5 seconds and we are still requesting, mark it as failed, otherwise continue
continue_attempt = int(Time.get_unix_time_from_system()) - attempt_start_time < 5
_:
## Something wrong happened; stop trying
continue_attempt = false
cli_print_callable.call("SYS_ERROR: Unable to connect to Github API, if you would like to attempt to reconnect please run 'call-_attempt_repo_connection'.")
repo_http_client.close()
return false
func get_latest_app_version() -> void:
if not repo_connection_succesfull:
cli_print_callable.call("SYS_ERROR: Attempted to get latest app version without being connected to the repo, please try to reconnect to the repo using 'call-_attempt_repo_connecton'.")
latest_version = "Unknown"
return
cli_print_callable.call("SYS: Attempting to fetch latest app version from Github.")
repo_http_client.request(HTTPClient.METHOD_GET, "/repos/NatZombieGames/Nat-Music-Programme/releases", ["accept:application/vnd.github+json", "X-GitHub-Api-Version:2022-11-28", "per_page:1"], '{"owner":"natzombiegames","repo":"nat-music-programme"}')
var continue_attempt : bool = true
var attempt_start_time : int = int(Time.get_unix_time_from_system())
while continue_attempt:
await get_tree().create_timer(0.25).timeout
repo_http_client.poll()
await get_tree().create_timer(0.25).timeout
match repo_http_client.get_status():
HTTPClient.Status.STATUS_BODY:
match repo_http_client.get_response_code():
HTTPClient.ResponseCode.RESPONSE_OK:
var response : Dictionary[String, Variant] = {}
## Get the response chunk, turn into utf8 string, parse it as JSON before getting the first item.
response.assign(JSON.parse_string(repo_http_client.read_response_body_chunk().get_string_from_utf8())[0])
cli_print_callable.call("SYS_ALERT: Succesfully retreived latest app version from Github.")
repo_http_client.close()
repo_connection_succesfull = false
## Each release name is the version, so we can just grab the name
latest_version = response["name"]
return
_:
cli_print_callable.call("SYS_ERROR: When fetching the latest app version received the response code '[u]" + str(repo_http_client.get_response_code()) + "[/u]' which is unhandled, unable to get latest app version.")
latest_version = "Unknown"
return
HTTPClient.Status.STATUS_REQUESTING:
## If it has taken over 5 seconds and we are still requesting, mark it as failed, otherwise continue
continue_attempt = int(Time.get_unix_time_from_system()) - attempt_start_time < 5
_:
## Something wrong happened; stop trying
continue_attempt = false
cli_print_callable.call("SYS_ERROR: Unable to get latest app version, either received unhandled status code or it took too long to connect. Received status code '[u]" + str(repo_http_client.get_status()) + "'[/u].")
latest_version = "Unknown"
return
This seems sufficiently rigorous to me but I am not sure, so I was wanting to see if there are any important things that should be kept in mind when making simple requests like these?
Thanks