11
11
import com .ai .qa .gateway .interfaces .dto .UserProfileGatewayResponse ;
12
12
import lombok .RequiredArgsConstructor ;
13
13
import lombok .extern .slf4j .Slf4j ;
14
+ import org .springframework .http .HttpStatus ;
14
15
import org .springframework .stereotype .Service ;
16
+ import org .springframework .web .server .ResponseStatusException ;
15
17
import reactor .core .publisher .Mono ;
16
18
import reactor .core .scheduler .Schedulers ;
17
19
@@ -25,37 +27,44 @@ public class AuthFacade {
25
27
26
28
public Mono <AuthResponseDTO > login (LoginGatewayRequestDTO request ) {
27
29
return Mono .fromCallable (() -> userServiceClient .login (request ))
28
- .subscribeOn (Schedulers .boundedElastic ());
30
+ .subscribeOn (Schedulers .boundedElastic ())
31
+ .onErrorMap (this ::mapFeignException );
29
32
}
30
33
31
34
public Mono <AuthResponseDTO > register (RegisterGatewayRequestDTO request ) {
32
35
return Mono .fromCallable (() -> userServiceClient .register (request ))
33
- .subscribeOn (Schedulers .boundedElastic ());
36
+ .subscribeOn (Schedulers .boundedElastic ())
37
+ .onErrorMap (this ::mapFeignException );
34
38
}
35
39
36
40
public Mono <UserProfileGatewayResponse > profile (Long userId ) {
37
41
return Mono .fromCallable (() -> userServiceClient .profile (userId ).getData ())
38
- .subscribeOn (Schedulers .boundedElastic ());
42
+ .subscribeOn (Schedulers .boundedElastic ())
43
+ .onErrorMap (this ::mapFeignException );
39
44
}
40
45
41
46
public Mono <UserProfileGatewayResponse > updateNickname (Long userId , UpdateNicknameGatewayRequest request ) {
42
47
return Mono .fromCallable (() -> userServiceClient .updateNickname (userId , request ).getData ())
43
- .subscribeOn (Schedulers .boundedElastic ());
48
+ .subscribeOn (Schedulers .boundedElastic ())
49
+ .onErrorMap (this ::mapFeignException );
44
50
}
45
51
46
52
public Mono <List <ChatSessionResponseDTO >> sessions (Long userId ) {
47
53
return Mono .fromCallable (() -> userServiceClient .sessions (userId ).getData ())
48
- .subscribeOn (Schedulers .boundedElastic ());
54
+ .subscribeOn (Schedulers .boundedElastic ())
55
+ .onErrorMap (this ::mapFeignException );
49
56
}
50
57
51
58
public Mono <ChatSessionResponseDTO > createSession (Long userId , CreateSessionGatewayRequest request ) {
52
59
return Mono .fromCallable (() -> userServiceClient .createSession (userId , request ).getData ())
53
- .subscribeOn (Schedulers .boundedElastic ());
60
+ .subscribeOn (Schedulers .boundedElastic ())
61
+ .onErrorMap (this ::mapFeignException );
54
62
}
55
63
56
64
public Mono <ChatSessionResponseDTO > getSession (Long userId , Long sessionId ) {
57
65
return Mono .fromCallable (() -> userServiceClient .getSession (userId , sessionId ).getData ())
58
- .subscribeOn (Schedulers .boundedElastic ());
66
+ .subscribeOn (Schedulers .boundedElastic ())
67
+ .onErrorMap (this ::mapFeignException );
59
68
}
60
69
61
70
public Mono <Void > deleteSession (Long userId , Long sessionId ) {
@@ -66,11 +75,43 @@ public Mono<Void> deleteSession(Long userId, Long sessionId) {
66
75
67
76
public Mono <List <ChatHistoryResponseDTO >> history (Long userId , Long sessionId , Integer limit ) {
68
77
return Mono .fromCallable (() -> userServiceClient .history (userId , sessionId , limit ).getData ())
69
- .subscribeOn (Schedulers .boundedElastic ());
78
+ .subscribeOn (Schedulers .boundedElastic ())
79
+ .onErrorMap (this ::mapFeignException );
70
80
}
71
81
72
82
public Mono <Boolean > isSessionOwnedBy (Long sessionId , Long userId ) {
73
83
return Mono .fromCallable (() -> Boolean .TRUE .equals (userServiceClient .isSessionOwnedBy (sessionId , userId ).getData ()))
74
- .subscribeOn (Schedulers .boundedElastic ());
84
+ .subscribeOn (Schedulers .boundedElastic ())
85
+ .onErrorMap (this ::mapFeignException );
86
+ }
87
+
88
+ private Throwable mapFeignException (Throwable throwable ) {
89
+ if (throwable instanceof feign .FeignException feignException ) {
90
+ HttpStatus status = HttpStatus .resolve (feignException .status ());
91
+ String message = extractMessage (feignException );
92
+ if (status == null ) {
93
+ status = HttpStatus .INTERNAL_SERVER_ERROR ;
94
+ }
95
+ return new ResponseStatusException (status , message , feignException );
96
+ }
97
+ return throwable ;
98
+ }
99
+
100
+ private String extractMessage (feign .FeignException feignException ) {
101
+ try {
102
+ String content = feignException .contentUTF8 ();
103
+ if (content == null || content .isBlank ()) {
104
+ return feignException .getMessage ();
105
+ }
106
+ // Attempt to parse downstream ApiResponse structure
107
+ java .util .Map <?, ?> map = new com .fasterxml .jackson .databind .ObjectMapper ().readValue (content , java .util .Map .class );
108
+ Object message = map .get ("message" );
109
+ if (message != null ) {
110
+ return message .toString ();
111
+ }
112
+ return content ;
113
+ } catch (Exception ex ) {
114
+ return feignException .getMessage ();
115
+ }
75
116
}
76
117
}
0 commit comments