1919import feign .Logger ;
2020import feign .Param ;
2121import feign .RequestLine ;
22+ import feign .Response ;
23+ import feign .codec .Decoder ;
24+ import feign .codec .ErrorDecoder ;
2225import feign .gson .GsonDecoder ;
2326import java .util .List ;
2427
2528/** adapted from {@code com.example.retrofit.GitHubClient} */
2629public class GitHubExample {
2730
2831 public static void main (String ... args ) throws InterruptedException {
32+ Decoder decoder = new GsonDecoder ();
2933 GitHub github =
3034 Feign .builder ()
31- .decoder (new GsonDecoder ())
35+ .decoder (decoder )
36+ .errorDecoder (new GitHubErrorDecoder (decoder ))
3237 .logger (new Logger .ErrorLogger ())
3338 .logLevel (Logger .Level .BASIC )
3439 .target (GitHub .class , "https://api.github.com" );
@@ -38,6 +43,12 @@ public static void main(String... args) throws InterruptedException {
3843 for (Contributor contributor : contributors ) {
3944 System .out .println (contributor .login + " (" + contributor .contributions + ")" );
4045 }
46+
47+ try {
48+ contributors = github .contributors ("netflix" , "some-unknown-project" );
49+ } catch (GitHubClientError e ) {
50+ System .out .println (e .error .message );
51+ }
4152 }
4253
4354 interface GitHub {
@@ -51,4 +62,50 @@ static class Contributor {
5162 String login ;
5263 int contributions ;
5364 }
65+
66+ static class ClientError {
67+
68+ String message ;
69+ List <Error > errors ;
70+ }
71+
72+ static class Error {
73+ String resource ;
74+ String field ;
75+ String code ;
76+ }
77+
78+ static class GitHubErrorDecoder implements ErrorDecoder {
79+
80+ final Decoder decoder ;
81+ final ErrorDecoder defaultDecoder = new ErrorDecoder .Default ();
82+
83+ public GitHubErrorDecoder (Decoder decoder ) {
84+ this .decoder = decoder ;
85+ }
86+
87+ public Exception decode (String methodKey , Response response ) {
88+ if (response .status () >= 400 && response .status () < 500 ) {
89+ try {
90+ ClientError error = (ClientError ) decoder .decode (response , ClientError .class );
91+ return new GitHubClientError (response .status (), error );
92+ } catch (Exception e ) {
93+ e .printStackTrace ();
94+ }
95+ }
96+ return defaultDecoder .decode (methodKey , response );
97+ }
98+ }
99+
100+ static class GitHubClientError extends RuntimeException {
101+
102+ private static final long serialVersionUID = 0 ;
103+
104+ ClientError error ;
105+
106+ protected GitHubClientError (int status , ClientError error ) {
107+ super ("client error " + status );
108+ this .error = error ;
109+ }
110+ }
54111}
0 commit comments