Skip to content

Commit de40948

Browse files
fractalwrenchkattrali
authored andcommitted
Track handled unhandled (#59)
1 parent d6e4504 commit de40948

9 files changed

Lines changed: 347 additions & 23 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.gradle
22
build/
3-
3+
*.iml
4+
out/
45
#
56
# Common IDE files
67
#

src/main/java/com/bugsnag/Bugsnag.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,9 @@ public boolean notify(Throwable throwable, Severity severity, Callback callback)
275275
return false;
276276
}
277277

278-
Report report = buildReport(throwable);
279-
report.setSeverity(severity);
278+
HandledState handledState = HandledState.newInstance(
279+
HandledState.SeverityReasonType.REASON_USER_SPECIFIED, severity);
280+
Report report = new Report(config, throwable, handledState);
280281
return notify(report, callback);
281282
}
282283

@@ -293,6 +294,12 @@ public boolean notify(Report report) {
293294
return notify(report, null);
294295
}
295296

297+
298+
boolean notify(Throwable throwable, HandledState handledState) {
299+
Report report = new Report(config, throwable, handledState);
300+
return notify(report, null);
301+
}
302+
296303
/**
297304
* Notify Bugsnag of an exception and provide custom diagnostic data
298305
* for this particular error report.

src/main/java/com/bugsnag/ExceptionHandler.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.lang.Thread.UncaughtExceptionHandler;
44
import java.util.WeakHashMap;
55

6+
67
class ExceptionHandler implements UncaughtExceptionHandler {
78
private final UncaughtExceptionHandler originalHandler;
89
private final WeakHashMap<Bugsnag, Boolean> clientMap = new WeakHashMap<Bugsnag, Boolean>();
@@ -45,7 +46,10 @@ static void disable(Bugsnag bugsnag) {
4546
public void uncaughtException(Thread thread, Throwable throwable) {
4647
// Notify any subscribed clients of the uncaught exception
4748
for (Bugsnag bugsnag : clientMap.keySet()) {
48-
bugsnag.notify(throwable, Severity.ERROR);
49+
50+
HandledState handledState = HandledState.newInstance(
51+
HandledState.SeverityReasonType.REASON_UNHANDLED_EXCEPTION, Severity.ERROR);
52+
bugsnag.notify(throwable, handledState);
4953
}
5054

5155
// Pass exception on to original exception handler
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.bugsnag;
2+
3+
final class HandledState {
4+
5+
enum SeverityReasonType {
6+
REASON_UNHANDLED_EXCEPTION("unhandledException"),
7+
REASON_HANDLED_EXCEPTION("handledException"),
8+
REASON_USER_SPECIFIED("userSpecifiedSeverity"),
9+
REASON_CALLBACK_SPECIFIED("userCallbackSetSeverity");
10+
11+
private final String name;
12+
13+
SeverityReasonType(String name) {
14+
this.name = name;
15+
}
16+
17+
@Override
18+
public String toString() {
19+
return name;
20+
}
21+
}
22+
23+
private final SeverityReasonType severityReasonType;
24+
private final Severity originalSeverity;
25+
private final boolean unhandled;
26+
27+
private Severity currentSeverity;
28+
29+
static HandledState newInstance(SeverityReasonType severityReasonType) {
30+
return newInstance(severityReasonType, null);
31+
}
32+
33+
static HandledState newInstance(SeverityReasonType severityReasonType, Severity severity) {
34+
switch (severityReasonType) {
35+
case REASON_UNHANDLED_EXCEPTION:
36+
return new HandledState(severityReasonType, Severity.ERROR, true);
37+
case REASON_HANDLED_EXCEPTION:
38+
return new HandledState(severityReasonType, Severity.WARNING, false);
39+
case REASON_USER_SPECIFIED:
40+
return new HandledState(severityReasonType, severity, false);
41+
default:
42+
throw new IllegalArgumentException("Invalid arg for reason: " + severityReasonType);
43+
}
44+
}
45+
46+
private HandledState(SeverityReasonType severityReasonType,
47+
Severity currentSeverity, boolean unhandled) {
48+
this.severityReasonType = severityReasonType;
49+
this.originalSeverity = currentSeverity;
50+
this.unhandled = unhandled;
51+
this.currentSeverity = currentSeverity;
52+
}
53+
54+
boolean isDefaultSeverity(Severity currentSeverity) {
55+
return originalSeverity == currentSeverity;
56+
}
57+
58+
boolean isUnhandled() {
59+
return unhandled;
60+
}
61+
62+
SeverityReasonType getSeverityReasonType() {
63+
return severityReasonType;
64+
}
65+
66+
Severity getOriginalSeverity() {
67+
return originalSeverity;
68+
}
69+
70+
SeverityReasonType calculateSeverityReasonType() {
71+
return originalSeverity == currentSeverity
72+
? severityReasonType
73+
: SeverityReasonType.REASON_CALLBACK_SPECIFIED;
74+
}
75+
76+
Severity getCurrentSeverity() {
77+
return currentSeverity;
78+
}
79+
80+
void setCurrentSeverity(Severity severity) {
81+
this.currentSeverity = severity;
82+
}
83+
84+
}

src/main/java/com/bugsnag/Report.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010
import java.util.Map;
1111

1212
public class Report {
13-
private static final String PAYLOAD_VERSION = "2";
13+
private static final String PAYLOAD_VERSION = "3";
1414

1515
private Configuration config;
1616

1717
private String apiKey;
1818
private Throwable throwable;
19-
private Severity severity = Severity.WARNING;
19+
private final HandledState handledState;
20+
private Severity severity;
2021
private String groupingHash;
2122
private Diagnostics diagnostics = new Diagnostics();
2223
private boolean shouldCancel = false;
@@ -28,8 +29,15 @@ public class Report {
2829
* @param throwable the error to create the report for.
2930
*/
3031
protected Report(Configuration config, Throwable throwable) {
32+
this(config, throwable, HandledState.newInstance(
33+
HandledState.SeverityReasonType.REASON_HANDLED_EXCEPTION));
34+
}
35+
36+
Report(Configuration config, Throwable throwable, HandledState handledState) {
3137
this.config = config;
3238
this.throwable = throwable;
39+
this.handledState = handledState;
40+
this.severity = handledState.getOriginalSeverity();
3341
}
3442

3543
@Expose
@@ -55,6 +63,16 @@ protected List<Exception> getExceptions() {
5563
return exceptions;
5664
}
5765

66+
@Expose
67+
boolean getUnhandled() {
68+
return handledState.isUnhandled();
69+
}
70+
71+
@Expose
72+
SeverityReason getSeverityReason() {
73+
return new SeverityReason(handledState.calculateSeverityReasonType().toString());
74+
}
75+
5876
@Expose
5977
protected List<ThreadState> getThreads() {
6078
return config.sendThreads ? ThreadState.getLiveThreads(config) : null;
@@ -216,6 +234,7 @@ public Report setGroupingHash(String groupingHash) {
216234
*/
217235
public Report setSeverity(Severity severity) {
218236
this.severity = severity;
237+
this.handledState.setCurrentSeverity(severity);
219238
return this;
220239
}
221240

@@ -257,4 +276,17 @@ public Report cancel() {
257276
public boolean getShouldCancel() {
258277
return this.shouldCancel;
259278
}
279+
280+
static class SeverityReason {
281+
private final String type;
282+
283+
SeverityReason(String type) {
284+
this.type = type;
285+
}
286+
287+
@Expose
288+
String getType() {
289+
return type;
290+
}
291+
}
260292
}

src/test/java/com/bugsnag/BugsnagTest.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,7 @@ public void testNoDeliveryFails() {
3131
@Test
3232
public void testIgnoreClasses() {
3333
Bugsnag bugsnag = new Bugsnag("apikey");
34-
bugsnag.setDelivery(new Delivery() {
35-
@Override
36-
public void deliver(Serializer serializer, Object object) {
37-
}
38-
39-
@Override
40-
public void close() {
41-
}
42-
});
34+
bugsnag.setDelivery(BugsnagTestUtils.generateDelivery());
4335

4436
// Ignore neither
4537
bugsnag.setIgnoreClasses();
@@ -60,15 +52,8 @@ public void close() {
6052
@Test
6153
public void testNotifyReleaseStages() {
6254
Bugsnag bugsnag = new Bugsnag("apikey");
63-
bugsnag.setDelivery(new Delivery() {
64-
@Override
65-
public void deliver(Serializer serializer, Object object) {
66-
}
55+
bugsnag.setDelivery(BugsnagTestUtils.generateDelivery());
6756

68-
@Override
69-
public void close() {
70-
}
71-
});
7257
bugsnag.setReleaseStage("production");
7358

7459
// Never send
@@ -339,6 +324,7 @@ public void close() {
339324
@Test
340325
public void testCallbackCancel() {
341326
Bugsnag bugsnag = new Bugsnag("apikey");
327+
bugsnag.setDelivery(BugsnagTestUtils.generateDelivery());
342328
bugsnag.addCallback(new Callback() {
343329
@Override
344330
public void beforeNotify(Report report) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.bugsnag;
2+
3+
import com.bugsnag.delivery.Delivery;
4+
import com.bugsnag.serialization.Serializer;
5+
6+
class BugsnagTestUtils {
7+
8+
static Delivery generateDelivery() {
9+
return new Delivery() {
10+
@Override
11+
public void deliver(Serializer serializer, Object object) {
12+
13+
}
14+
15+
@Override
16+
public void close() {
17+
18+
}
19+
};
20+
}
21+
}

0 commit comments

Comments
 (0)