Skip to content

Refactor cURL error handling to preserve response data - #75

Merged
MarcelKemp merged 4 commits into
1.0.0from
dev/32416_curl_error_log
Oct 17, 2025
Merged

Refactor cURL error handling to preserve response data#75
MarcelKemp merged 4 commits into
1.0.0from
dev/32416_curl_error_log

Conversation

@GabrielEValenzuela

@GabrielEValenzuela GabrielEValenzuela commented Oct 9, 2025

Copy link
Copy Markdown

Closes wazuh/wazuh#32416

Summary

This change refactors the cURL execution logic to improve error handling and diagnostics. Specifically, it allows the CurlException to carry the HTTP response code while preserving the response body for inspection in case of errors.

Problem Statement

Previously, the cURL handler would reset the easy handle (curl_easy_reset) immediately after an error, which cleared any buffered response data. This made it impossible to access the server’s response body in failure cases (e.g., 4xx/5xx responses).

Additionally, the use of OPT_FAILONERROR caused curl_easy_perform() to fail automatically on HTTP errors (≥ 400), without giving us a chance to read the full response.

Observed behavior:

  • On HTTP 4xx/5xx responses, curl_easy_perform() returned CURLE_HTTP_RETURNED_ERROR.
  • The handle was reset before the exception was thrown.
  • The application lost the response body, preventing detailed error reporting or diagnostics.

Expected behavior:

  • On failure, response data should still be available to the caller.
  • The exception should contain the HTTP response code.
  • The cURL handle should only be reset after successful execution.

Solution

The execute() method in the cURL handler has been refactored to preserve the response context and provide richer exceptions.

1. Defer curl_easy_reset()

The reset now occurs only on success, ensuring the response data remains accessible when an exception is thrown:

// Only reset on success
curl_easy_reset(m_curlHandler.get());

2. Preserve Response and HTTP Code on Errors

When CURLE_HTTP_RETURNED_ERROR occurs, the HTTP response code is retrieved and passed into the CurlException, allowing downstream consumers to handle errors based on status code:

if (resPerform == CURLE_HTTP_RETURNED_ERROR)
{
    if (resGetInfo != CURLE_OK)
    {
        throw std::runtime_error("cURLSingleHandler::execute() failed: Couldn't get HTTP response code");
    }
    // Throw exception WITHOUT resetting - response data is still available
    throw Curl::CurlException(curl_easy_strerror(resPerform), responseCode);
}

3. Remove OPT_FAILONERROR

The following option is now commented out:

// this->setOptionLong(OPT_FAILONERROR, 1l);

This prevents automatic failure on HTTP errors, letting the new execute() logic handle them manually while still capturing the response body.

Changes Made

  • curlSingleHandler.cpp

    • Moved curl_easy_reset() to only execute on successful requests.
    • Updated exception handling to include response codes and preserve body data.
    • Improved runtime error messages for missing response info.
  • curlWrapper.hpp

    • Updated CurlException to accept an optional HTTP response code argument.
  • Removed automatic fail-on-error option (OPT_FAILONERROR) to allow full response capture on server errors.

@GabrielEValenzuela
GabrielEValenzuela requested review from a team and Copilot October 9, 2025 16:38
@GabrielEValenzuela GabrielEValenzuela self-assigned this Oct 9, 2025

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the cURL error handling to preserve HTTP response data and include response codes in exceptions. The changes address the issue where response bodies were lost when HTTP errors occurred due to premature handle resets.

  • Deferred curl_easy_reset() to only execute after successful requests
  • Enhanced CurlException to optionally store response body data
  • Removed automatic failure on HTTP errors to allow response capture

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/curlWrapper.hpp Added try-catch to preserve response body in CurlException and disabled auto-fail on HTTP errors
src/curlSingleHandler.hpp Moved curl_easy_reset to only execute on success, preserving response data for error cases
shared/curlException.hpp Enhanced CurlException class to store and provide access to HTTP response body

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread src/curlWrapper.hpp Outdated
Comment thread shared/curlException.hpp Outdated
@GabrielEValenzuela GabrielEValenzuela changed the title Refactor cURL error handling to preserve response data and include HTTP code in exceptions Refactor cURL error handling to preserve response data Oct 9, 2025
@GabrielEValenzuela GabrielEValenzuela linked an issue Oct 13, 2025 that may be closed by this pull request
2 tasks
Comment thread src/curlSingleHandler.hpp Outdated
Comment thread src/curlSingleHandler.hpp Outdated
Comment thread src/curlWrapper.hpp Outdated
Comment thread src/curlSingleHandler.hpp Outdated

@MarcelKemp MarcelKemp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@MarcelKemp
MarcelKemp merged commit 6eca14e into 1.0.0 Oct 17, 2025
2 checks passed
@MarcelKemp
MarcelKemp deleted the dev/32416_curl_error_log branch October 17, 2025 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve logging on Manager

3 participants