@@ -56,6 +56,26 @@ static ErrorInfo HttpFunctionInfo(const char *subtype, const std::string &base_u
5656 return info;
5757}
5858
59+ // Error context for a request whose worker error comes back in the HTTP body:
60+ // the worker (base URL), this execution, and the function. `url` is the
61+ // request route, reported as its own field.
62+ static RpcErrorContext HttpCallErrorContext (const std::string &base_url, const std::string &url,
63+ const std::string &method, const std::string &function_name,
64+ const std::string &function_type, const std::string &execution_id_hex,
65+ const std::string &attach_opaque_data_digest,
66+ const std::string &conn_id_hex) {
67+ RpcErrorContext ctx;
68+ ctx.worker_path = base_url;
69+ ctx.execution_id_hex = execution_id_hex;
70+ ctx.attach_opaque_data_digest = attach_opaque_data_digest;
71+ ctx.conn_id_hex = conn_id_hex;
72+ auto info = HttpFunctionInfo (nullptr , base_url, function_name, function_type);
73+ info.erase (error_key::kErrorSubtype );
74+ info.Url (url).Rpc (method);
75+ ctx.fields .insert (info.begin (), info.end ());
76+ return ctx;
77+ }
78+
5979// Helper: parse ``vgi_batch_index`` off Arrow custom_metadata.
6080// Returns INVALID_INDEX when the key is absent. Raises IOException
6181// when present but un-parseable. The cap and monotonicity checks
@@ -423,10 +443,12 @@ BindResult HttpFunctionConnection::PerformBindRpc() {
423443 // In/out capability snapshot: picks this request's Content-Encoding and
424444 // is refreshed from the response (see CurrentCapabilities).
425445 ServerCapabilities b_caps = CurrentCapabilities ();
446+ const auto call_error_fields = HttpFunctionInfo (nullptr , base_url_, function_name_, function_type_);
426447 auto resp = HttpInvokeUnary (context_, base_url_, " bind" , rpc_params, auth,
427448 /* cookie_jar=*/ nullptr , cached_params,
428449 " " , " " , " " , " " , VGI_MAIN_PROTOCOL , &http_client_, &b_caps,
429- attach_params_ ? attach_params_->iroh () : nullptr );
450+ attach_params_ ? attach_params_->iroh () : nullptr ,
451+ &call_error_fields);
430452 PublishHarvestedCapabilities (b_caps);
431453 if (!resp.batch || resp.batch ->num_rows () == 0 ) {
432454 throw IOException (HttpFunctionInfo (error_subtype::kProtocolViolation , base_url_, function_name_, function_type_).Rpc (" bind" ), " Empty bind response from HTTP server [url: %s]" , base_url_);
@@ -578,10 +600,12 @@ InitResult HttpFunctionConnection::PerformInit(const BindResult &bind_result,
578600 // codec is right on the first try (see CurrentCapabilities); refreshed from
579601 // the response below.
580602 ServerCapabilities harvested = CurrentCapabilities ();
603+ const auto call_error_context = HttpCallErrorContext (base_url_, init_url, " init" , function_name_, function_type_,
604+ GetExecutionIdHex (), GetAttachOpaqueDataDigest (), GetConnIdHex ());
581605 auto response_body = HttpPostArrowIpc (context_, init_url, body, auth,
582606 /* cookie_jar=*/ nullptr , cached_params_init, &http_client_,
583607 &harvested, attach_params_ ? attach_params_->iroh () : nullptr ,
584- &context_.interrupted );
608+ &context_.interrupted , &call_error_context );
585609 PublishHarvestedCapabilities (harvested);
586610#ifdef __EMSCRIPTEN__
587611#endif
@@ -806,11 +830,13 @@ HttpFunctionConnection::RpcTableBufferingProcess(const std::string &function_nam
806830 auto cached_params = attach_params_ && IsHttpTransport (base_url_)
807831 ? attach_params_->GetOrInitHttpParams (context_, base_url_) : nullptr ;
808832 ServerCapabilities tb_caps = CurrentCapabilities ();
833+ const auto call_error_fields = HttpFunctionInfo (nullptr , base_url_, function_name_, function_type_);
809834 auto resp = HttpInvokeUnary (context_, base_url_, " table_buffering_process" , rpc_params, auth,
810835 /* cookie_jar=*/ nullptr , cached_params,
811836 GetExecutionIdHex (), GetAttachOpaqueDataDigest (), " " , GetConnIdHex (),
812837 VGI_MAIN_PROTOCOL , &http_client_, &tb_caps,
813- attach_params_ ? attach_params_->iroh () : nullptr );
838+ attach_params_ ? attach_params_->iroh () : nullptr ,
839+ &call_error_fields);
814840 PublishHarvestedCapabilities (tb_caps);
815841 auto inner = DecodeHttpOuterResponse (resp, " table_buffering_process" , base_url_);
816842 if (!inner || inner->num_rows () == 0 ) {
@@ -834,11 +860,13 @@ HttpFunctionConnection::RpcTableBufferingCombine(const std::string &function_nam
834860 auto cached_params = attach_params_ && IsHttpTransport (base_url_)
835861 ? attach_params_->GetOrInitHttpParams (context_, base_url_) : nullptr ;
836862 ServerCapabilities tb_caps = CurrentCapabilities ();
863+ const auto call_error_fields = HttpFunctionInfo (nullptr , base_url_, function_name_, function_type_);
837864 auto resp = HttpInvokeUnary (context_, base_url_, " table_buffering_combine" , rpc_params, auth,
838865 /* cookie_jar=*/ nullptr , cached_params,
839866 GetExecutionIdHex (), GetAttachOpaqueDataDigest (), " " , GetConnIdHex (),
840867 VGI_MAIN_PROTOCOL , &http_client_, &tb_caps,
841- attach_params_ ? attach_params_->iroh () : nullptr );
868+ attach_params_ ? attach_params_->iroh () : nullptr ,
869+ &call_error_fields);
842870 PublishHarvestedCapabilities (tb_caps);
843871 auto inner = DecodeHttpOuterResponse (resp, " table_buffering_combine" , base_url_);
844872 if (!inner || inner->num_rows () == 0 ) {
@@ -868,11 +896,13 @@ void HttpFunctionConnection::RpcTableBufferingDestructor(const std::string &func
868896 auto cached_params = attach_params_ && IsHttpTransport (base_url_)
869897 ? attach_params_->GetOrInitHttpParams (context_, base_url_) : nullptr ;
870898 ServerCapabilities tb_caps = CurrentCapabilities ();
899+ const auto call_error_fields = HttpFunctionInfo (nullptr , base_url_, function_name_, function_type_);
871900 auto resp = HttpInvokeUnary (context_, base_url_, " table_buffering_destructor" , rpc_params, auth,
872901 /* cookie_jar=*/ nullptr , cached_params,
873902 GetExecutionIdHex (), GetAttachOpaqueDataDigest (), " " , GetConnIdHex (),
874903 VGI_MAIN_PROTOCOL , &http_client_, &tb_caps,
875- attach_params_ ? attach_params_->iroh () : nullptr );
904+ attach_params_ ? attach_params_->iroh () : nullptr ,
905+ &call_error_fields);
876906 PublishHarvestedCapabilities (tb_caps);
877907 auto inner = DecodeHttpOuterResponse (resp, " table_buffering_destructor" , base_url_);
878908 (void )inner;
@@ -929,10 +959,12 @@ std::shared_ptr<arrow::RecordBatch> HttpFunctionConnection::ReadDataBatch() {
929959 auto p_cached_params = attach_params_ && IsHttpTransport (exchange_url)
930960 ? attach_params_->GetOrInitHttpParams (context_, exchange_url) : nullptr ;
931961 ServerCapabilities p_harvested = CurrentCapabilities ();
962+ const auto call_error_context = HttpCallErrorContext (base_url_, exchange_url, " exchange" , function_name_, function_type_,
963+ GetExecutionIdHex (), GetAttachOpaqueDataDigest (), GetConnIdHex ());
932964 auto response_body = HttpPostArrowIpc (context_, exchange_url, body, p_auth,
933965 /* cookie_jar=*/ nullptr , p_cached_params, &http_client_,
934966 &p_harvested, attach_params_ ? attach_params_->iroh () : nullptr ,
935- &context_.interrupted );
967+ &context_.interrupted , &call_error_context );
936968 PublishHarvestedCapabilities (p_harvested);
937969
938970 // Parse response — buffer new data batches (adopt the body, no copy)
@@ -1007,10 +1039,12 @@ std::shared_ptr<arrow::RecordBatch> HttpFunctionConnection::ReadDataBatch() {
10071039 auto x_cached_params = attach_params_ && IsHttpTransport (exchange_url)
10081040 ? attach_params_->GetOrInitHttpParams (context_, exchange_url) : nullptr ;
10091041 ServerCapabilities x_harvested = CurrentCapabilities ();
1042+ const auto call_error_context = HttpCallErrorContext (base_url_, exchange_url, " exchange" , function_name_, function_type_,
1043+ GetExecutionIdHex (), GetAttachOpaqueDataDigest (), GetConnIdHex ());
10101044 auto response_body = HttpPostArrowIpc (context_, exchange_url, body, x_auth,
10111045 /* cookie_jar=*/ nullptr , x_cached_params, &http_client_,
10121046 &x_harvested, attach_params_ ? attach_params_->iroh () : nullptr ,
1013- &context_.interrupted );
1047+ &context_.interrupted , &call_error_context );
10141048 PublishHarvestedCapabilities (x_harvested);
10151049
10161050 // Parse response — copy into owning buffer since Arrow IPC reads zero-copy reference it
0 commit comments