11package org .gitlab4j .api ;
22
3+ import java .util .ArrayList ;
4+ import java .util .HashMap ;
5+ import java .util .Iterator ;
6+ import java .util .List ;
7+ import java .util .Map ;
8+ import java .util .Map .Entry ;
9+
10+ import javax .ws .rs .core .MediaType ;
311import javax .ws .rs .core .Response ;
412import javax .ws .rs .core .Response .StatusType ;
513
6- import org .gitlab4j .api .models .ErrorMessage ;
14+ import org .gitlab4j .api .utils .JacksonJson ;
15+
16+ import com .fasterxml .jackson .databind .JsonNode ;
717
818/**
919 * This is the exception that will be thrown if any exception occurs while communicating
@@ -15,6 +25,7 @@ public class GitLabApiException extends Exception {
1525 private StatusType statusInfo ;
1626 private int httpStatus ;
1727 private String message ;
28+ private Map <String , List <String >> validationErrors ;
1829
1930 /**
2031 * Create a GitLabApiException instance with the specified message.
@@ -28,7 +39,7 @@ public GitLabApiException(String message) {
2839
2940 /**
3041 * Create a GitLabApiException instance based on the ClientResponse.
31- *
42+ *
3243 * @param response the JAX-RS response that caused the exception
3344 */
3445 public GitLabApiException (Response response ) {
@@ -38,10 +49,50 @@ public GitLabApiException(Response response) {
3849 httpStatus = response .getStatus ();
3950
4051 if (response .hasEntity ()) {
52+
4153 try {
4254
43- ErrorMessage errorMessage = response .readEntity (ErrorMessage .class );
44- message = errorMessage .getMessage ();
55+ String message = response .readEntity (String .class );
56+ this .message = message ;
57+
58+ // Determine what is in the content of the response and process it accordingly
59+ MediaType mediaType = response .getMediaType ();
60+ if (mediaType != null && "json" .equals (mediaType .getSubtype ())) {
61+
62+ JsonNode json = JacksonJson .toJsonNode (message );
63+
64+ // First see if it is a "message", if so it is either a simple message,
65+ // or a Map<String, List<String>> of validation errors
66+ JsonNode jsonMessage = json .get ("message" );
67+ if (jsonMessage != null ) {
68+
69+ // If the node is an object, then it is validation errors
70+ if (jsonMessage .isObject ()) {
71+
72+ validationErrors = new HashMap <>();
73+ Iterator <Entry <String , JsonNode >> fields = jsonMessage .fields ();
74+ while (fields .hasNext ()) {
75+
76+ Entry <String , JsonNode > field = fields .next ();
77+ List <String > values = new ArrayList <>();
78+ validationErrors .put (field .getKey (), values );
79+ for (JsonNode value : field .getValue ()) {
80+ values .add (value .asText ());
81+ }
82+ }
83+
84+ } else {
85+ this .message = jsonMessage .asText ();
86+ }
87+
88+ } else {
89+
90+ JsonNode jsonError = json .get ("error" );
91+ if (jsonError != null ) {
92+ this .message = jsonError .asText ();
93+ }
94+ }
95+ }
4596
4697 } catch (Exception ignore ) {
4798 }
@@ -50,7 +101,7 @@ public GitLabApiException(Response response) {
50101
51102 /**
52103 * Create a GitLabApiException instance based on the exception.
53- *
104+ *
54105 * @param e the Exception to wrap
55106 */
56107 public GitLabApiException (Exception e ) {
@@ -60,7 +111,7 @@ public GitLabApiException(Exception e) {
60111
61112 /**
62113 * Get the message associated with the exception.
63- *
114+ *
64115 * @return the message associated with the exception
65116 */
66117 @ Override
@@ -71,7 +122,7 @@ public final String getMessage() {
71122 /**
72123 * Returns the HTTP status reason message, returns null if the
73124 * causing error was not an HTTP related exception.
74- *
125+ *
75126 * @return the HTTP status reason message
76127 */
77128 public final String getReason () {
@@ -81,10 +132,32 @@ public final String getReason() {
81132 /**
82133 * Returns the HTTP status code that was the cause of the exception. returns 0 if the
83134 * causing error was not an HTTP related exception.
84- *
135+ *
85136 * @return the HTTP status code, returns 0 if the causing error was not an HTTP related exception
86137 */
87138 public final int getHttpStatus () {
88139 return (httpStatus );
89140 }
141+
142+ /**
143+ * Returns true if this GitLabApiException was caused by validation errors on the GitLab server,
144+ * otherwise returns false.
145+ *
146+ * @return true if this GitLabApiException was caused by validation errors on the GitLab server,
147+ * otherwise returns false
148+ */
149+ public boolean hasValidationErrors () {
150+ return (validationErrors != null );
151+ }
152+
153+ /**
154+ * Returns a Map<String, List<String>> instance containing validation errors if this GitLabApiException
155+ * was caused by validation errors on the GitLab server, otherwise returns null.
156+ *
157+ * @return a Map<String, List<String>> instance containing validation errors if this GitLabApiException
158+ * was caused by validation errors on the GitLab server, otherwise returns null
159+ */
160+ public Map <String , List <String >> getValidationErrors () {
161+ return (validationErrors );
162+ }
90163}
0 commit comments