@@ -43,14 +43,20 @@ uri_v3(mlf::MLFlow, endpoint::String;
4343"""
4444 headers(mlf::MLFlow,custom_headers::AbstractDict)
4545
46- Retrieves HTTP headers based on `mlf` and merges with user-provided `custom_headers`
46+ Retrieves HTTP headers based on `mlf` and merges with user-provided `custom_headers`.
47+
48+ `Connection: close` is set by default so each request uses a fresh connection. MLflow's
49+ server (gunicorn) closes idle keep-alive connections after a couple of seconds, while the
50+ HTTP client keeps them pooled for much longer; reusing such a stale connection surfaces as
51+ `unexpected EOF while reading HTTP/1 data`. Disabling reuse avoids that class of error.
4752
4853# Examples
4954```@example
5055headers(mlf,Dict("Content-Type"=>"application/json"))
5156```
5257"""
53- headers (mlf:: MLFlow , custom_headers:: AbstractDict ) = merge (mlf. headers, custom_headers)
58+ headers (mlf:: MLFlow , custom_headers:: AbstractDict ) =
59+ merge (Dict (" Connection" => " close" ), mlf. headers, custom_headers)
5460
5561"""
5662 mlfget(mlf, endpoint; kwargs...)
@@ -66,6 +72,10 @@ function mlfget(mlf, endpoint; kwargs...)
6672 response = HTTP. get (apiuri, apiheaders)
6773 return response. body |> String |> JSON. parse
6874 catch e
75+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
76+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
77+ # instead of masking them with a FieldError on `e.response`.
78+ e isa HTTP. StatusError || rethrow ()
6979 error_response = e. response. body |> String |> JSON. parse
7080 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
7181 @error error_message
@@ -88,6 +98,10 @@ function mlfpost(mlf, endpoint; kwargs...)
8898 response = HTTP. post (apiuri, apiheaders, body)
8999 return response. body |> String |> JSON. parse
90100 catch e
101+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
102+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
103+ # instead of masking them with a FieldError on `e.response`.
104+ e isa HTTP. StatusError || rethrow ()
91105 error_response = e. response. body |> String |> JSON. parse
92106 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
93107 @error error_message
@@ -110,6 +124,10 @@ function mlfpatch(mlf, endpoint; kwargs...)
110124 response = HTTP. patch (apiuri, apiheaders, body)
111125 return response. body |> String |> JSON. parse
112126 catch e
127+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
128+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
129+ # instead of masking them with a FieldError on `e.response`.
130+ e isa HTTP. StatusError || rethrow ()
113131 error_response = e. response. body |> String |> JSON. parse
114132 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
115133 @error error_message
@@ -135,6 +153,10 @@ function mlfdelete(mlf, endpoint; kwargs...)
135153 # Some v3 endpoints (e.g. workspaces/delete) return an empty body on success.
136154 return isempty (strip (response_body)) ? Dict {String,Any} () : JSON. parse (response_body)
137155 catch e
156+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
157+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
158+ # instead of masking them with a FieldError on `e.response`.
159+ e isa HTTP. StatusError || rethrow ()
138160 error_response = e. response. body |> String |> JSON. parse
139161 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
140162 @error error_message
@@ -156,6 +178,10 @@ function mlfget_v3(mlf, endpoint; kwargs...)
156178 response = HTTP. get (apiuri, apiheaders)
157179 return response. body |> String |> JSON. parse
158180 catch e
181+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
182+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
183+ # instead of masking them with a FieldError on `e.response`.
184+ e isa HTTP. StatusError || rethrow ()
159185 error_response = e. response. body |> String |> JSON. parse
160186 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
161187 @error error_message
@@ -178,6 +204,10 @@ function mlfpost_v3(mlf, endpoint; kwargs...)
178204 response = HTTP. post (apiuri, apiheaders, body)
179205 return response. body |> String |> JSON. parse
180206 catch e
207+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
208+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
209+ # instead of masking them with a FieldError on `e.response`.
210+ e isa HTTP. StatusError || rethrow ()
181211 error_response = e. response. body |> String |> JSON. parse
182212 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
183213 @error error_message
@@ -200,6 +230,10 @@ function mlfpatch_v3(mlf, endpoint; kwargs...)
200230 response = HTTP. patch (apiuri, apiheaders, body)
201231 return response. body |> String |> JSON. parse
202232 catch e
233+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
234+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
235+ # instead of masking them with a FieldError on `e.response`.
236+ e isa HTTP. StatusError || rethrow ()
203237 error_response = e. response. body |> String |> JSON. parse
204238 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
205239 @error error_message
@@ -225,6 +259,10 @@ function mlfdelete_v3(mlf, endpoint; kwargs...)
225259 # Some v3 endpoints (e.g. workspaces/delete) return an empty body on success.
226260 return isempty (strip (response_body)) ? Dict {String,Any} () : JSON. parse (response_body)
227261 catch e
262+ # Only HTTP error responses (4xx/5xx) carry a `.response` with an MLflow error
263+ # body; connection/parse errors (e.g. HTTP.ParseError) do not, so rethrow those
264+ # instead of masking them with a FieldError on `e.response`.
265+ e isa HTTP. StatusError || rethrow ()
228266 error_response = e. response. body |> String |> JSON. parse
229267 error_message = " $(error_response[" error_code" ]) - $(error_response[" message" ]) "
230268 @error error_message
0 commit comments