return r;
}
+static int pakfire_buildservice_handle_error(struct pakfire_buildservice* service,
+ struct pakfire_transfer* transfer, const struct json_object* error) {
+ struct json_object* message = NULL;
+ struct json_object* code = NULL;
+ const char* m = NULL;
+ unsigned int c = 0;
+
+ // Fetch the URL
+ const char* url = pakfire_downloader_transfer_get_effective_url(transfer);
+
+ // Fetch the code
+ if (!json_object_object_get_ex(error, "code", &code))
+ return -EBADMSG;
+
+ // Check if the code is an integer
+ if (!json_object_is_type(code, json_type_int))
+ return -EBADMSG;
+
+ // Fetch the message
+ if (!json_object_object_get_ex(error, "message", &message))
+ return -EBADMSG;
+
+ // Check if the message is a string
+ if (!json_object_is_type(message, json_type_string))
+ return -EBADMSG;
+
+ c = json_object_get_uint64(code);
+ m = json_object_get_string(message);
+
+ // Log the error
+ CTX_ERROR(service->ctx, "%s responded with error %u:\n %s\n", url, c, m);
+
+ // Translate the codes
+ switch (c) {
+ case 400:
+ return -EINVAL;
+
+ default:
+ break;
+ }
+
+ return 1;
+}
+
+/*
+ This function parses an API response
+*/
+static int pakfire_buildservice_parse_response(struct pakfire_buildservice* service,
+ struct pakfire_transfer* transfer, const char* buffer, const size_t length,
+ struct json_object** object) {
+ struct json_object* error = NULL;
+ struct json_object* o = NULL;
+ int r;
+
+ // XXX Maybe fetch the parser's error message here?!
+
+ // Parse the buffer
+ o = pakfire_json_parse(service->ctx, buffer, length);
+ if (!o) {
+ CTX_ERROR(service->ctx, "Could not parse the response\n");
+ r = -EBADMSG;
+ goto ERROR;
+ }
+
+ // Check if the response is a dictionary
+ if (!json_object_is_type(o, json_type_object)) {
+ CTX_ERROR(service->ctx, "The received object is not a JSON dict\n");
+ r = -EBADMSG;
+ goto ERROR;
+ }
+
+ // Fetch error
+ r = json_object_object_get_ex(o, "error", &error);
+ if (r) {
+ r = pakfire_buildservice_handle_error(service, transfer, error);
+ goto ERROR;
+ }
+
+ // Return the object
+ *object = o;
+
+ return 0;
+
+ERROR:
+ if (o)
+ json_object_put(o);
+
+ return r;
+}
+
// Uploads
static int pakfire_buildservice_create_upload(struct pakfire_buildservice* service,
if (r)
goto ERROR;
- // Parse the JSON response
- response = pakfire_json_parse(service->ctx, buffer, length);
- if (!response) {
- CTX_ERROR(service->ctx, "Could not parse response\n");
- r = -EBADMSG;
+ // Parse the response
+ r = pakfire_buildservice_parse_response(service, transfer, buffer, length, &response);
+ if (r) {
+ CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
goto ERROR;
}
static int pakfire_buildservice_upload_payload(struct pakfire_buildservice* service,
const char* filename, const char* uuid, FILE* f) {
struct pakfire_transfer* transfer = NULL;
+ struct json_object* response = NULL;
+ char* buffer = NULL;
+ size_t length = 0;
char url[PATH_MAX];
int r;
if (r)
goto ERROR;
+ // Set the output buffer
+ r = pakfire_downloader_transfer_set_output_buffer(transfer, &buffer, &length);
+ if (r)
+ goto ERROR;
+
// Run the transfer
r = pakfire_downloader_transfer_run(transfer, 0);
if (r)
goto ERROR;
+ // Parse the response
+ r = pakfire_buildservice_parse_response(service, transfer, buffer, length, &response);
+ if (r) {
+ CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
+ goto ERROR;
+ }
+
ERROR:
if (transfer)
pakfire_downloader_transfer_unref(transfer);
+ if (response)
+ json_object_put(response);
return r;
}
if (r)
goto ERROR;
- // XXX would be nice to have the JSON error here
-
// Parse the response
- response = pakfire_json_parse(service->ctx, buffer, length);
- if (!response) {
- CTX_ERROR(service->ctx, "Could not parse the response\n");
- r = -EBADMSG;
+ r = pakfire_buildservice_parse_response(service, transfer, buffer, length, &response);
+ if (r) {
+ CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
goto ERROR;
}