Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 027e4b4

Browse filesBrowse files
Better error message: introduce HttpException, subclass of IOException with url, http responseCode and http responseMessage to help exception handling.
1 parent dbc79f8 commit 027e4b4
Copy full SHA for 027e4b4

File tree

Expand file treeCollapse file tree

4 files changed

+157
-4
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+157
-4
lines changed

‎pom.xml

Copy file name to clipboardExpand all lines: pom.xml
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@
4646
</execution>
4747
</executions>
4848
</plugin>
49+
<plugin>
50+
<groupId>org.apache.maven.plugins</groupId>
51+
<artifactId>maven-compiler-plugin</artifactId>
52+
<configuration>
53+
<source>1.6</source>
54+
<target>1.6</target>
55+
</configuration>
56+
</plugin>
4957
<plugin>
5058
<groupId>org.codehaus.mojo</groupId>
5159
<artifactId>findbugs-maven-plugin</artifactId>

‎src/main/java/org/kohsuke/github/GitHub.java

Copy file name to clipboardExpand all lines: src/main/java/org/kohsuke/github/GitHub.java
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.io.IOException;
3232
import java.io.InputStreamReader;
3333
import java.io.Reader;
34+
import java.net.HttpURLConnection;
3435
import java.net.MalformedURLException;
3536
import java.net.URL;
3637
import java.text.ParseException;
@@ -55,6 +56,8 @@
5556
import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std;
5657
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
5758
import java.nio.charset.Charset;
59+
import java.util.logging.Level;
60+
import java.util.logging.Logger;
5861

5962
/**
6063
* Root of the GitHub API.
@@ -68,6 +71,8 @@
6871
* @author Kohsuke Kawaguchi
6972
*/
7073
public class GitHub {
74+
protected final transient Logger logger = Logger.getLogger(getClass().getName());
75+
7176
/*package*/ final String login;
7277

7378
/**
@@ -458,6 +463,7 @@ public boolean isCredentialValid() throws IOException {
458463
retrieve().to("/user", GHUser.class);
459464
return true;
460465
} catch (IOException e) {
466+
logger.log(Level.FINEST, "Exception validating credentials on {0} with login {1}: {2}", new Object[]{this.apiUrl, this.login, e, e});
461467
return false;
462468
}
463469
}
+119Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package org.kohsuke.github;
2+
3+
import java.io.IOException;
4+
import java.net.HttpURLConnection;
5+
import java.net.URL;
6+
7+
/**
8+
* Http exception
9+
*
10+
* @author <a href="mailto:cleclerc@cloudbees.com">Cyrille Le Clerc</a>
11+
*/
12+
public class HttpException extends IOException {
13+
static final long serialVersionUID = 1L;
14+
15+
private final int responseCode;
16+
private final String responseMessage;
17+
private final String url;
18+
19+
/**
20+
* @param message The detail message (which is saved for later retrieval
21+
* by the {@link #getMessage()} method)
22+
* @param responseCode Http response code. {@code -1} if no code can be discerned.
23+
* @param responseMessage Http response message
24+
* @param url The url that was invoked
25+
* @see HttpURLConnection#getResponseCode()
26+
* @see HttpURLConnection#getResponseMessage()
27+
*/
28+
public HttpException(String message, int responseCode, String responseMessage, String url) {
29+
super(message);
30+
this.responseCode = responseCode;
31+
this.responseMessage = responseMessage;
32+
this.url = url;
33+
}
34+
35+
/**
36+
* @param message The detail message (which is saved for later retrieval
37+
* by the {@link #getMessage()} method)
38+
* @param responseCode Http response code. {@code -1} if no code can be discerned.
39+
* @param responseMessage Http response message
40+
* @param url The url that was invoked
41+
* @param cause The cause (which is saved for later retrieval by the
42+
* {@link #getCause()} method). (A null value is permitted,
43+
* and indicates that the cause is nonexistent or unknown.)
44+
* @see HttpURLConnection#getResponseCode()
45+
* @see HttpURLConnection#getResponseMessage()
46+
*/
47+
public HttpException(String message, int responseCode, String responseMessage, String url, Throwable cause) {
48+
super(message, cause);
49+
this.responseCode = responseCode;
50+
this.responseMessage = responseMessage;
51+
this.url = url;
52+
}
53+
54+
/**
55+
* @param message The detail message (which is saved for later retrieval
56+
* by the {@link #getMessage()} method)
57+
* @param responseCode Http response code. {@code -1} if no code can be discerned.
58+
* @param responseMessage Http response message
59+
* @param url The url that was invoked
60+
* @param cause The cause (which is saved for later retrieval by the
61+
* {@link #getCause()} method). (A null value is permitted,
62+
* and indicates that the cause is nonexistent or unknown.)
63+
* @see HttpURLConnection#getResponseCode()
64+
* @see HttpURLConnection#getResponseMessage()
65+
*/
66+
public HttpException(int responseCode, String responseMessage, String url, Throwable cause) {
67+
super("Server returned HTTP response code: " + responseCode + ", message: '" + responseMessage + "'" +
68+
" for URL: " + url, cause);
69+
this.responseCode = responseCode;
70+
this.responseMessage = responseMessage;
71+
this.url = url;
72+
}
73+
74+
/**
75+
* @param responseCode Http response code. {@code -1} if no code can be discerned.
76+
* @param responseMessage Http response message
77+
* @param url The url that was invoked
78+
* @param cause The cause (which is saved for later retrieval by the
79+
* {@link #getCause()} method). (A null value is permitted,
80+
* and indicates that the cause is nonexistent or unknown.)
81+
* @see HttpURLConnection#getResponseCode()
82+
* @see HttpURLConnection#getResponseMessage()
83+
*/
84+
public HttpException(int responseCode, String responseMessage, URL url, Throwable cause) {
85+
this(responseCode, responseMessage, url == null ? null : url.toString(), cause);
86+
}
87+
88+
/**
89+
* Http response code of the request that cause the exception
90+
*
91+
* @return {@code -1} if no code can be discerned.
92+
*/
93+
public int getResponseCode() {
94+
return responseCode;
95+
}
96+
97+
/**
98+
* Http response message of the request that cause the exception
99+
*
100+
* @return {@code null} if no response message can be discerned.
101+
*/
102+
public String getResponseMessage() {
103+
return responseMessage;
104+
}
105+
106+
/**
107+
* The http URL that caused the exception
108+
*
109+
* @return url
110+
*/
111+
public String getUrl() {
112+
return url;
113+
}
114+
115+
@Override
116+
public String getMessage() {
117+
return super.getMessage();
118+
}
119+
}

‎src/main/java/org/kohsuke/github/Requester.java

Copy file name to clipboardExpand all lines: src/main/java/org/kohsuke/github/Requester.java
+24-4Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -473,21 +473,33 @@ private void setupConnection(URL url) throws IOException {
473473
}
474474

475475
private <T> T parse(Class<T> type, T instance) throws IOException {
476-
if (uc.getResponseCode()==304)
477-
return null; // special case handling for 304 unmodified, as the content will be ""
478476
InputStreamReader r = null;
477+
int responseCode = -1;
478+
String responseMessage = null;
479479
try {
480+
responseCode = uc.getResponseCode();
481+
responseMessage = uc.getResponseMessage();
482+
if (responseCode == 304) {
483+
return null; // special case handling for 304 unmodified, as the content will be ""
484+
}
485+
480486
r = new InputStreamReader(wrapStream(uc.getInputStream()), "UTF-8");
481487
String data = IOUtils.toString(r);
482488
if (type!=null)
483489
try {
484490
return MAPPER.readValue(data,type);
485491
} catch (JsonMappingException e) {
486-
throw (IOException)new IOException("Failed to deserialize "+data).initCause(e);
492+
throw (IOException)new IOException("Failed to deserialize " +data).initCause(e);
487493
}
488494
if (instance!=null)
489495
return MAPPER.readerForUpdating(instance).<T>readValue(data);
490496
return null;
497+
} catch (FileNotFoundException e) {
498+
// java.net.URLConnection handles 404 exception has FileNotFoundException, don't wrap exception in HttpException
499+
// to preserve backward compatibility
500+
throw e;
501+
} catch (IOException e) {
502+
throw new HttpException(responseCode, responseMessage, uc.getURL(), e);
491503
} finally {
492504
IOUtils.closeQuietly(r);
493505
}
@@ -508,7 +520,15 @@ private InputStream wrapStream(InputStream in) throws IOException {
508520
* Handle API error by either throwing it or by returning normally to retry.
509521
*/
510522
/*package*/ void handleApiError(IOException e) throws IOException {
511-
if (uc.getResponseCode() == 401) // Unauthorized == bad creds
523+
int responseCode;
524+
try {
525+
responseCode = uc.getResponseCode();
526+
} catch (IOException e2) {
527+
// likely to be a network exception (e.g. SSLHandshakeException),
528+
// uc.getResponseCode() and any other getter on the response will cause an exception
529+
throw e;
530+
}
531+
if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 / Unauthorized == bad creds
512532
throw e;
513533

514534
if ("0".equals(uc.getHeaderField("X-RateLimit-Remaining"))) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.