From 015576b2ba2051b4462b0f8ae6d912755d09799d Mon Sep 17 00:00:00 2001 From: Jamiras <32680403+Jamiras@users.noreply.github.com> Date: Wed, 20 Jan 2021 19:07:48 -0800 Subject: [PATCH] improve error handling for achievement unlocks (#11916) --- cheevos/cheevos.c | 36 +++++++++++++++++++++++++++++++++--- menu/cbs/menu_cbs_ok.c | 2 +- retroarch.c | 4 ++-- tasks/task_http.c | 23 ++++++++++++++++++----- tasks/tasks_internal.h | 1 + 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 0b7e3a1419..275c6c5f5e 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -621,12 +621,34 @@ static void rcheevos_async_task_callback( retro_task_t* task, void* task_data, void* user_data, const char* error) { rcheevos_async_io_request* request = (rcheevos_async_io_request*)user_data; + http_transfer_data_t* data = (http_transfer_data_t*)task_data; if (!error) { - char buffer[224]; - const http_transfer_data_t* data = (http_transfer_data_t*)task->task_data; - if (rcheevos_get_json_error(data->data, buffer, sizeof(buffer)) == RC_OK) + char buffer[224] = ""; + if (!data) + { + /* server did not return HTTP headers */ + snprintf(buffer, sizeof(buffer), "Server communication error"); + } + else if (data->status != 200) + { + /* server returned an error via status code - check to see if it also returned a JSON error */ + if (!data->data || rcheevos_get_json_error(data->data, buffer, sizeof(buffer)) != RC_OK) + snprintf(buffer, sizeof(buffer), "HTTP error code: %d", data->status); + } + else if (!data->data || !data->len) + { + /* server sent an empty response without an error status code */ + snprintf(buffer, sizeof(buffer), "No response from server"); + } + else + { + /* server sent a message - assume its JSON and check for a JSON error */ + rcheevos_get_json_error(data->data, buffer, sizeof(buffer)); + } + + if (buffer[0]) { char errbuf[256]; snprintf(errbuf, sizeof(errbuf), "%s %u: %s", request->failure_message, request->id, buffer); @@ -669,6 +691,14 @@ static void rcheevos_async_task_callback( CHEEVOS_ERR(RCHEEVOS_TAG "%s %u: %s\n", request->failure_message, request->id, error); } + + if (data) + { + if (data->data) + free(data->data); + + free(data); + } } static void rcheevos_activate_achievements(rcheevos_locals_t *locals, diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 46bbf1e028..24ef8151ea 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -4248,7 +4248,7 @@ static void cb_net_generic(retro_task_t *task, menu->core_buf = NULL; menu->core_len = 0; - if (!data || err) + if (!data || err || !data->data) goto finish; menu->core_buf = (char*)malloc((data->len+1) * sizeof(char)); diff --git a/retroarch.c b/retroarch.c index d0fe95863d..9917f39c21 100644 --- a/retroarch.c +++ b/retroarch.c @@ -5947,7 +5947,7 @@ static void handle_discord_join_cb(retro_task_t *task, struct rarch_state *p_rarch = &rarch_st; discord_state_t *discord_st = &p_rarch->discord_st; - if (!data || err) + if (!data || err || !data->data) goto finish; data->data = (char*)realloc(data->data, data->len + 1); @@ -10648,7 +10648,7 @@ static void handle_translation_cb( RARCH_LOG("RESULT FROM AI SERVICE...\n"); #endif - if (!data || error) + if (!data || error || !data->data) goto finish; json = rjson_open_buffer(data->data, data->len); diff --git a/tasks/task_http.c b/tasks/task_http.c index 976ad60176..0632713408 100644 --- a/tasks/task_http.c +++ b/tasks/task_http.c @@ -191,15 +191,28 @@ task_finished: free(tmp); if (task_get_cancelled(task)) + { task_set_error(task, strdup("Task cancelled.")); - else if (!task->mute) - task_set_error(task, strdup("Download failed.")); + } + else + { + data = (http_transfer_data_t*)malloc(sizeof(*data)); + data->data = NULL; + data->len = 0; + data->status = net_http_status(http->handle); + + task_set_data(task, data); + + if (!task->mute) + task_set_error(task, strdup("Download failed.")); + } } else { - data = (http_transfer_data_t*)malloc(sizeof(*data)); - data->data = tmp; - data->len = len; + data = (http_transfer_data_t*)malloc(sizeof(*data)); + data->data = tmp; + data->len = len; + data->status = net_http_status(http->handle); task_set_data(task, data); } diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index a13c815973..5c7e0dc754 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -55,6 +55,7 @@ typedef struct { char *data; size_t len; + int status; } http_transfer_data_t; void *task_push_http_transfer(const char *url, bool mute, const char *type,