Skip to content

Add explicit HTTP timeouts and map downstream failures in UserServiceClient (auth-path call) #10

Description

@simonforsberg

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo_root="$(pwd)"
file="authService/src/main/java/org/example/authservice/client/UserServiceClient.java"

echo "== File: $file =="
wc -l "$file"
nl -ba "$file" | sed -n '1,220p'

echo
echo "== Search for RestClient.builder usage (possible shared config) =="
rg -n "RestClient\.builder\(" authService/src/main/java || true

echo
echo "== Search for timeout configuration in authService =="
rg -n "timeout|connectTimeout|readTimeout|responseTimeout" authService/src/main/java || true

echo
echo "== Search for HttpClientErrorException mapping patterns in authService =="
rg -n "HttpClientErrorException|retrieve\(\)\.body\(|Optional\.empty\(" authService/src/main/java/org/example/authservice/client || true

Repository: simonforsberg/relay

Length of output: 299


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="authService/src/main/java/org/example/authservice/client/UserServiceClient.java"

echo "== File: $file =="
wc -l "$file"
echo
echo "== Contents (numbered) =="
cat -n "$file" | sed -n '1,140p'

echo
echo "== Search for RestClient.builder usage (broader authService) =="
rg -n "RestClient\.builder\(" authService/src/main/java || true

echo
echo "== Search for any timeout configuration (authService) =="
rg -n "(connectTimeout|readTimeout|responseTimeout|timeout|Timeout)" authService/src/main/java || true

echo
echo "== Search for exception mapping in this client (authService client package) =="
rg -n "(HttpClientErrorException|retrieve\(\)\.body|body\(|Optional\.empty\(|NotFound)" authService/src/main/java/org/example/authservice/client || true

echo
echo "== Search for any RestClient customizers/config shared across the repo =="
rg -n "RestClient|connectTimeout|readTimeout|responseTimeout|Timeout" . || true

Repository: simonforsberg/relay

Length of output: 3046


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for any RestClient.Builder bean/config =="
rg -n "RestClient\.Builder|RestClient\.builder\(|`@Bean`\s+.*RestClient|`@Bean`\s+RestClient" . || true

echo
echo "== Search for underlying HTTP client timeouts (repo-wide) =="
rg -n "(connectTimeout|readTimeout|responseTimeout|connectionTimeout|socketTimeout|requestTimeout|Timeout)" . || true

echo
echo "== Search for HTTP client factories/connectors =="
rg -n "(ClientHttpRequestFactory|HttpComponentsClientHttpRequestFactory|OkHttpClient|HttpClient\s*\{|HttpUrlConnection|RequestConfig|Timeout)" . || true

echo
echo "== Search for WebClient usage (in case timeouts handled there) =="
rg -n "WebClient\.builder\(|WebClient" . || true

Repository: simonforsberg/relay

Length of output: 1000


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List likely config files
echo "== List authService application config files =="
fd -e yml -e yaml -e properties "application" authService || true
fd -e yml -e yaml -e properties authService -a 2>/dev/null || true

echo
echo "== Search for userservice.internal.base-url =="
rg -n "userservice\.internal\.base-url" . || true

echo
echo "== Search for timeout-related Spring/Web properties =="
rg -n "(timeout|connect-timeout|read-timeout|response-timeout|connection-timeout|request-timeout|spring\.web\.client|RestClient)" authService/src/main/resources || true

echo
echo "== Search for any rest client / HTTP client configuration classes in authService =="
rg -n "(RestClient|ClientHttpRequestFactory|HttpClient|RequestConfig|builder\(\)\.baseUrl|RestClient\.builder)" authService/src/main/java || true

Repository: simonforsberg/relay

Length of output: 1334


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="authService/src/main/resources/application.properties"
echo "== Contents: $file =="
cat -n "$file" | sed -n '1,200p'

Repository: simonforsberg/relay

Length of output: 472


🌐 Web query:

Spring Framework RestClient.builder default timeouts connect/read when no timeout configured

💡 Result:

In Spring Framework’s RestClient.Builder, if you do not configure a ClientHttpRequestFactory, RestClient selects one of several underlying HTTP-client implementations (Apache HttpClient, Jetty HttpClient, Reactor Netty, JDK HttpClient, or a “simple” default) based on what’s on the classpath [1][2]. Because the chosen implementation is different, Spring itself does not publish a single fixed default “connect timeout” and “read timeout” for RestClient; the effective connect/read timeout behavior comes from the defaults of the underlying ClientHttpRequestFactory/HTTP client [1][2]. What you can say confidently from the sources: 1) RestClient does not define its own connect/read timeout defaults at the builder level when no request factory is provided; it delegates to the request factory it initializes [2]. 2) The timeout behavior therefore depends on which request factory is picked (Apache/Jetty/Reactor Netty/JDK/simple) [2]. If you need deterministic connect/read timeouts, you must configure the ClientHttpRequestFactory yourself via RestClient.Builder.requestFactory(...) [1][2]. For example, SimpleClientHttpRequestFactory documents that a connect/read timeout of 0 means “infinite timeout” and that defaults are system defaults if you don’t set them [3]. Answer to the query “default timeouts connect/read when no timeout configured”: There is no single universal default connect/read timeout specified by RestClient.Builder; with no requestFactory configured, RestClient uses an implementation-specific request factory, and the effective connect/read timeouts are whatever that underlying factory/client defaults to [2].

Citations:


Add explicit HTTP timeouts and map downstream failures in UserServiceClient (auth-path call)

authService/src/main/java/org/example/authservice/client/UserServiceClient.java (lines 16–31) builds RestClient with only baseUrl and no requestFactory(...), so connect/read timeouts fall back to the underlying HTTP client defaults. findByUsername only maps HttpClientErrorException.NotFound; other HTTP errors and transport/timeouts will propagate and can cascade/fail the authentication flow.

Configure deterministic connect/read timeouts via RestClient.Builder.requestFactory(...), and handle timeouts/5xx/other non-404 failures with a controlled auth-service exception (or fallback) instead of letting them bubble up.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@authService/src/main/java/org/example/authservice/client/UserServiceClient.java`
around lines 16 - 31, UserServiceClient currently builds RestClient without
requestFactory so timeouts default and findByUsername only maps NotFound; update
the UserServiceClient constructor to configure
RestClient.builder().requestFactory(...) with explicit connect/read timeouts
(use a ClientHttpRequestFactory or HttpComponentsClientHttpRequestFactory) so
calls have deterministic timeouts, and modify findByUsername to catch and map
transport/timeouts and 5xx errors (e.g.,
ResourceAccessException/SocketTimeoutException and HttpServerErrorException) to
a controlled auth-service exception or fallback return (instead of letting them
propagate), keeping the NotFound path returning Optional.empty(); reference
constructor RestClient.builder(), requestFactory(...) and method findByUsername
for changes.

Originally posted by @coderabbitai[bot] in #9 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions