]> git.ipfire.org Git - pakfire.git/commitdiff
xfer: Add a function to fetch a useful error from the API
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 27 Jun 2025 09:50:39 +0000 (09:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 27 Jun 2025 09:50:39 +0000 (09:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/cli/lib/client-build.c
src/pakfire/xfer.c
src/pakfire/xfer.h

index 9bb09acd58d3e8c943889b84ef650e2b24be9f3b..37fc19df848920a939b37782de7fb6f338f62288 100644 (file)
@@ -101,23 +101,33 @@ static error_t parse(int key, char* arg, struct argp_state* state, void* data) {
 static int build_callback(struct pakfire_xfer* xfer,
                const pakfire_xfer_response* response, void* data) {
        const char* uuid = NULL;
+       char* error = NULL;
        int r;
 
        // Handle errors
        if (response->error) {
-               fprintf(stderr, "Failed to create build\n");
-               return 1;
+               r = pakfire_xfer_response_get_error(response, &error);
+               if (r < 0)
+                       goto ERROR;
+
+               fprintf(stderr, "Failed to create build: %s\n", error);
+               r = 1;
+               goto ERROR;
        }
 
        // Fetch the UUID
        r = pakfire_json_get_string(response->data, "uuid", &uuid);
        if (r < 0)
-               return r;
+               goto ERROR;
 
        // Show status
        printf("Created build %s\n", uuid);
 
-       return 0;
+ERROR:
+       if (error)
+               free(error);
+
+       return r;
 }
 
 // Called when an upload was successful
index a88cb82ce6afbf36e279c77fcf4ed1e57e4f031d..e759070b712aa2780a78a71018b0393271ceec96 100644 (file)
@@ -715,6 +715,78 @@ int pakfire_xfer_set_response_callback(struct pakfire_xfer* self,
        return 0;
 }
 
+int pakfire_xfer_response_get_error(const pakfire_xfer_response* response, char** error) {
+       const char* detail = NULL;
+       int r;
+
+       // The API did not respond with an error
+       if (!response->error)
+               return -EINVAL;
+
+       // Process the body if we have one
+       if (response->data) {
+               // Fetch the detail
+               r = pakfire_json_get_string(response->data, "detail", &detail);
+               if (r < 0)
+                       return r;
+
+               // Format the error string
+               if (detail)
+                       return asprintf(error, "%d - %s", response->status, detail);
+       }
+
+       // Show the status code
+       if (response->status)
+               return asprintf(error, "HTTP Status %d", response->status);
+
+       // As a last resort, we show the xfer code
+       switch (response->error) {
+               case PAKFIRE_XFER_OK:
+                       return asprintf(error, "OK");
+
+               case PAKFIRE_XFER_FAILED:
+                       return asprintf(error, "Unknown Error");
+
+               case PAKFIRE_XFER_UNSUPPORTED:
+                       return asprintf(error, "Unsupported Protocol");
+
+               case PAKFIRE_XFER_INVALID_URL:
+                       return asprintf(error, "Invalid URL");
+
+               case PAKFIRE_XFER_INVALID_RESPONSE:
+                       return asprintf(error, "Invalid Response");
+
+               case PAKFIRE_XFER_DNS_ERROR:
+                       return asprintf(error, "DNS Error");
+
+               case PAKFIRE_XFER_AUTH_ERROR:
+                       return asprintf(error, "Authentication Error");
+
+               case PAKFIRE_XFER_ACCESS_DENIED:
+                       return asprintf(error, "Access Denied");
+
+               case PAKFIRE_XFER_TRANSPORT_ERROR:
+                       return asprintf(error, "Transport Error");
+
+               case PAKFIRE_XFER_TIMEOUT:
+                       return asprintf(error, "Timeout");
+
+               case PAKFIRE_XFER_WRITE_ERROR:
+                       return asprintf(error, "Write Error");
+
+               case PAKFIRE_XFER_READ_ERROR:
+                       return asprintf(error, "Read Error");
+
+               case PAKFIRE_XFER_ABORTED:
+                       return asprintf(error, "Aborted");
+
+               case PAKFIRE_XFER_DIGEST_MISMATCH:
+                       return asprintf(error, "Digest Mismatch");
+       }
+
+       return 0;
+}
+
 int pakfire_xfer_set_input(struct pakfire_xfer* xfer, FILE* f) {
        struct stat stat;
        int r;
index 57bb64493188d226bca0da56fb25f57f10cd8edd..342c63969b50b8241067a7b32601830612082770 100644 (file)
@@ -138,12 +138,16 @@ int pakfire_xfer_set_output(struct pakfire_xfer* xfer, FILE* f);
 int pakfire_xfer_set_output_buffer(struct pakfire_xfer* xfer, char** buffer, size_t* length);
 int pakfire_xfer_set_output_path(struct pakfire_xfer* xfer, const char* path);
 
+// Response
+
 typedef int (*pakfire_xfer_response_callback)
        (struct pakfire_xfer* xfer, const pakfire_xfer_response* response, void* data);
 
 int pakfire_xfer_set_response_callback(struct pakfire_xfer* xfer,
        pakfire_xfer_response_callback callback, void* data);
 
+int pakfire_xfer_response_get_error(const pakfire_xfer_response* response, char** error);
+
 // Input
 int pakfire_xfer_set_input(struct pakfire_xfer* xfer, FILE* f);