Author: brane
Date: Mon Jan 12 23:56:57 2026
New Revision: 1931277

Log:
Add a simple test to verify error propagation through the callbacks.
Only for context and outgoing connection/requests for now, no incoming
or SSL stuff.

* serf_private.h
  (serf__global_error_callback): Declare the default global error callback.
* src/error_callbacks.c
  (serf__global_error_callback): Renamed from default_global_error_callback
   and made public instead of static. All references updated.
* test/test_internal.c
  (struct error_callback_baton,
   error_cb_request_setup,
   error_cb_error_callback): New; private helpers.
  (test_global_error_callback): New test case.
  (test_internal): Register test_global_error_callback.

Modified:
   serf/trunk/serf_private.h
   serf/trunk/src/error_callbacks.c
   serf/trunk/test/test_internal.c

Modified: serf/trunk/serf_private.h
==============================================================================
--- serf/trunk/serf_private.h   Mon Jan 12 20:10:02 2026        (r1931276)
+++ serf/trunk/serf_private.h   Mon Jan 12 23:56:57 2026        (r1931277)
@@ -122,6 +122,13 @@ typedef int serf__bool_t; /* Not _Bool *
 
 /*** Error callback invocation ***/
 
+/* This is the default global error callback, used only in
+   error_callbacks.c and test_internal.c. */
+apr_status_t serf__global_error_callback(void *baton,
+                                         unsigned source,
+                                         apr_status_t status,
+                                         const char *message);
+
 /* NOTE: There is no serf__global_error() because the global handler
          should not be called directly but only as a fallback. */
 

Modified: serf/trunk/src/error_callbacks.c
==============================================================================
--- serf/trunk/src/error_callbacks.c    Mon Jan 12 20:10:02 2026        
(r1931276)
+++ serf/trunk/src/error_callbacks.c    Mon Jan 12 23:56:57 2026        
(r1931277)
@@ -23,17 +23,17 @@
 
 /* Global error processing. */
 
-static apr_status_t
-default_global_error_callback(void *baton,
-                              unsigned source,
-                              apr_status_t status,
-                              const char *message)
+apr_status_t
+serf__global_error_callback(void *baton,
+                            unsigned source,
+                            apr_status_t status,
+                            const char *message)
 {
     return APR_SUCCESS;
 }
 
 static void *global_error_callback_baton = NULL;
-static serf_error_cb_t global_error_callback = default_global_error_callback;
+static serf_error_cb_t global_error_callback = serf__global_error_callback;
 
 void serf_global_error_callback_set(serf_error_cb_t callback, void *baton)
 {

Modified: serf/trunk/test/test_internal.c
==============================================================================
--- serf/trunk/test/test_internal.c     Mon Jan 12 20:10:02 2026        
(r1931276)
+++ serf/trunk/test/test_internal.c     Mon Jan 12 23:56:57 2026        
(r1931277)
@@ -573,6 +573,87 @@ static void test_find_token(CuTest *tc)
     CuAssertPtrEquals(tc, NULL, serf__find_token("foo", 3, " qux bar"));
 }
 
+/*
+ * Error callbacks
+ */
+
+struct error_callback_baton
+{
+    apr_pool_t *pool;
+    apr_array_header_t *list;
+};
+
+static apr_status_t
+error_cb_request_setup(serf_request_t *request,
+                       void *setup_baton,
+                       serf_bucket_t **req_bkt,
+                       serf_response_acceptor_t *acceptor,
+                       void **acceptor_baton,
+                       serf_response_handler_t *handler,
+                       void **handler_baton,
+                       apr_pool_t *pool)
+{
+    return APR_SUCCESS;
+}
+
+static apr_status_t
+error_cb_error_callback(void *baton,
+                        unsigned source,
+                        apr_status_t status,
+                        const char *message)
+{
+    const struct error_callback_baton *const ecb = baton;
+    const char *const msg = apr_psprintf(
+        ecb->pool, "<%d> %c%c%c%c%c %s", status,
+        ((source & SERF_ERROR_CB_SSL_CONTEXT) ? '*' : '-'),
+        ((source & SERF_ERROR_CB_GLOBAL) ? 'g' : '-'),
+        ((source & SERF_ERROR_CB_CONTEXT) ? 'c' : '-'),
+        ((source & SERF_ERROR_CB_OUTGOING) ? 'o'
+         : ((source & SERF_ERROR_CB_INCOMING) ? 'i' : '-')),
+        ((source & SERF_ERROR_CB_REQUEST) ? 'q'
+         : ((source & SERF_ERROR_CB_RESPONSE) ? 'p' : '-')),
+        message);
+    APR_ARRAY_PUSH(ecb->list, const char*) = msg;
+    return APR_SUCCESS;
+}
+
+static void test_global_error_callback(CuTest *tc)
+{
+    test_baton_t *const tb = tc->testBaton;
+    struct error_callback_baton ecb;
+    serf_context_t *ctx;
+    serf_connection_t *conn;
+    serf_request_t *req;
+    apr_uri_t url;
+
+    ecb.pool = tb->pool;
+    ecb.list = apr_array_make(ecb.pool, 3, sizeof(const char*));
+    serf_global_error_callback_set(error_cb_error_callback, &ecb);
+
+    /* Create a context and connection. */
+    ctx = serf_context_create(ecb.pool);
+    apr_uri_parse(tb->pool, "http://localhost:12345";, &url);
+    serf_connection_create2(&conn, ctx, url, conn_setup, NULL,
+                            conn_closed, NULL, tb->pool);
+    req = serf_connection_request_create(conn, error_cb_request_setup, NULL);
+
+    serf__context_error(ctx, APR_SUCCESS, "context error");
+    serf__connection_error(conn, SERF_ERROR_CLOSING, "connection error");
+    serf__request_error(req, SERF_ERROR_REQUEST_LOST, "request error");
+
+    /* Reset the error callback before checking the test results. */
+    serf_global_error_callback_set(serf__global_error_callback, NULL);
+
+    CuAssertPtrEquals(tc, ctx, conn->ctx);
+    CuAssertIntEquals(tc, 3, ecb.list->nelts);
+    CuAssertStrEquals(tc, "<0> --c-- context error",
+                      APR_ARRAY_IDX(ecb.list, 0, const char*));
+    CuAssertStrEquals(tc, "<120101> ---o- connection error",
+                      APR_ARRAY_IDX(ecb.list, 1, const char*));
+    CuAssertStrEquals(tc, "<120102> ---oq request error",
+                      APR_ARRAY_IDX(ecb.list, 2, const char*));
+}
+
 
 CuSuite *test_internal(void)
 {
@@ -594,6 +675,7 @@ CuSuite *test_internal(void)
     SUITE_ADD_TEST(suite, test_parse_single_token_parameters);
     SUITE_ADD_TEST(suite, test_parameter_case_folding);
     SUITE_ADD_TEST(suite, test_find_token);
+    SUITE_ADD_TEST(suite, test_global_error_callback);
 
     return suite;
 }

Reply via email to