Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Bugsnag reports when errors are encountered #108

Merged
merged 12 commits into from
Jan 7, 2019
Merged

Conversation

evansiroky
Copy link

@evansiroky evansiroky commented Aug 6, 2018

The goal of this PR is to try to catch all possible halt-inducing exceptions that result in an HTTP >= 500 error and create Bugsnag reports from the exception.

@landonreed
Copy link
Member

landonreed commented Aug 7, 2018

@evansiroky this PR has changes for for many of the old editor controllers (e.g., /src/main/java/com/conveyal/datatools/editor/controllers/api/AgencyController.java). Instead of updating the halts, we might should just remove these classes altogether because they are no longer in use and, unlike the editor model classes, they are not needed for migrating from the MapDB-backed editor.

@evansiroky
Copy link
Author

@landonreed I don't know which classes those are. Would you be able to remove them in a separate PR and then I can build on top of that?

@evansiroky evansiroky requested a review from landonreed August 8, 2018 06:57
Copy link
Member

@landonreed landonreed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good. Just a few changes needed. Although I do have a mild concern about having to pass the request object to the haltWithMessage method, simply because it requires passing the request to downstream methods that might need to halt (e.g., downloadFile). So, I wonder if another approach might keep things a bit tighter or maybe we just remove the halt from downloadFile and always wrap it in a try/catch (throwing the halt in the catch).

@codecov-io
Copy link

codecov-io commented Aug 8, 2018

Codecov Report

Merging #108 into dev will increase coverage by 0.02%.
The diff coverage is 1.11%.

Impacted file tree graph

@@            Coverage Diff             @@
##               dev    #108      +/-   ##
==========================================
+ Coverage     5.15%   5.17%   +0.02%     
- Complexity      93      94       +1     
==========================================
  Files          133     133              
  Lines         6872    6875       +3     
  Branches       903     905       +2     
==========================================
+ Hits           354     356       +2     
- Misses        6490    6491       +1     
  Partials        28      28
Impacted Files Coverage Δ Complexity Δ
...conveyal/datatools/manager/models/FeedVersion.java 0% <ø> (ø) 0 <0> (ø) ⬇️
.../conveyal/datatools/manager/models/FeedSource.java 6.14% <0%> (ø) 3 <0> (ø) ⬇️
...nveyal/datatools/manager/codec/LocalDateCodec.java 20% <0%> (-1.43%) 3 <0> (ø)
...ols/manager/controllers/api/ProjectController.java 12.9% <0%> (-0.22%) 2 <0> (ø)
...atools/manager/controllers/api/UserController.java 7.77% <0%> (ø) 2 <0> (ø) ⬇️
...xtensions/transitland/TransitLandFeedResource.java 6.32% <0%> (-0.09%) 3 <0> (ø)
...ensions/transitfeeds/TransitFeedsFeedResource.java 7.5% <0%> (-0.1%) 3 <0> (ø)
...va/com/conveyal/datatools/manager/ConvertMain.java 0% <0%> (ø) 0 <0> (ø) ⬇️
.../com/conveyal/datatools/editor/jobs/GisExport.java 0% <0%> (ø) 0 <0> (ø) ⬇️
.../manager/controllers/api/FeedSourceController.java 8.72% <0%> (-0.31%) 2 <0> (ø)
... and 22 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d22da45...33eb392. Read the comment docs.

@evansiroky evansiroky mentioned this pull request Aug 12, 2018
@landonreed landonreed self-assigned this Oct 10, 2018
@landonreed landonreed assigned evansiroky and unassigned landonreed Nov 5, 2018
Copy link
Member

@landonreed landonreed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few changes/comments that need addressing. Also, could you update the PR description to better describe the changes?

@@ -202,66 +214,45 @@ public File getFeed (String id) {
/**
* Create a new feed with the given ID.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this method doc needs a little more info about what it does.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually not sure what this does. Help?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is obviously legacy code, so maybe it's outside the scope of your changes, but since you touched the method it made me notice that (to me) the javadoc doesn't really describe at all what the method does especially since the storeFeedLocally method has been removed from the internals. I would suggest that it say something like:

Store GTFS file locally. This method is used when a new feed version or generated GTFS file
(e.g., the product of merging multiple GTFS files from a project) needs to be stored locally for
future use. Note: uploading the file to S3 is handled elsewhere as a finishing step, e.g., at the
conclusion of a successful feed processing/validation step.

@evansiroky evansiroky changed the title Add better logging of server-side errors Create Bugsnag reports when errors are encountered Nov 7, 2018
@evansiroky
Copy link
Author

See questions in unresolved conversations. Otherwise this should be good to go.

@landonreed
Copy link
Member

Thanks @evansiroky. I just addressed the questions.

@landonreed landonreed assigned evansiroky and unassigned landonreed Nov 8, 2018
@evansiroky
Copy link
Author

Comments added, ready to merge?

@evansiroky evansiroky assigned landonreed and unassigned evansiroky Nov 8, 2018
Copy link
Member

@landonreed landonreed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @evansiroky, sorry for the late response on this. Upon further review, I have a few more comments/changes and it looks like it needs to be updated to fix merge conflicts as well.

return date;
} catch (Exception jsonException) {
// This is here to catch any loads of database dumps that happen to have the old java.util.Date
// field type in validationResult. God help us.
System.out.println("Error parsing date value, trying legacy java.util.Date date format");
LOG.warn(
String.format("Error parsing date value: `%s`, trying legacy java.util.Date date format", dateText)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOG.warn has string substitution if you use {}:

LOG.warn("Error parsing date value: `{}`, trying legacy java.util.Date date format", dateText)

try {
date = Instant.ofEpochMilli(jp.getValueAsLong()).atZone(ZoneOffset.UTC).toLocalDate();
return date;
} catch (Exception e) {
LOG.warn(
String.format("Error parsing date value: `%s`", dateText)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above comment about string substitution in LOG.warn.

LOG.error("Unable to open input stream from upload");
haltWithMessage(req, 500, "an unexpected error occurred", e);
haltWithMessage(req, 400, "Unable to open input stream from upload", e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the early comment about having haltWithMessage also log messages. This would keep things DRY-er here.

@@ -140,7 +138,7 @@ private static Project deleteProject(Request req, Response res) {
Project project = requestProjectById(req, "manage");
boolean successfullyDeleted = project.delete();
if (!successfullyDeleted) {
haltWithMessage(req, 400, "Did not delete project.");
haltWithMessage(req, 500, "Did not delete project.", new Exception("Delete unsuccessful"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem great to be just creating arbitrary exceptions here that are not really tied back to the "failing" code. Do we gain anything by having a bugsnag report that points back here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is possible to create a Bugsnag report without an exception. So I think what we'd gain here is receiving a Bugsnag report that the user received a 500 error from the server.

try {
DataManager.feedResources.get(syncType).importFeedsForProject(proj, req.headers("Authorization"));
} catch (Exception e) {
haltWithMessage(req, 500, "An error occurred while trying to sync", e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this PR partially intended to remove generic exceptions? Does this hinder its purpose?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most important part of this PR is the creation of bugsnag reports whenever a 500 error halt occurs. Wherever possible I think it's good to be as specific as possible to create better error reports, but I think it's fine to catch generic exceptions too. In this specific case, the abstract class method only specifies the Exception class as something that is thrown.

@@ -360,6 +365,7 @@ public static ScheduledFuture scheduleAutoFeedFetch (Project project, int interv
return DataManager.scheduler.scheduleAtFixedRate(fetchProjectFeedsJob,
delayInMinutes, TimeUnit.DAYS.toMinutes(intervalInDays), minutes);
} catch (Exception e) {
LOG.error("Failed to schedule auto feed fetch");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this register an error with bugsnag?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure why not?

@@ -74,8 +76,8 @@ public void importFeedsForProject(Project project, String authHeader) {
con.setRequestProperty("User-Agent", "User-Agent");

int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
LOG.info("\nSending 'GET' request to URL : " + url);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove this new line char.

@landonreed landonreed assigned evansiroky and unassigned landonreed Dec 11, 2018
@evansiroky
Copy link
Author

comments should be addressed, merge conflicts resolved.

@evansiroky evansiroky assigned landonreed and unassigned evansiroky Dec 12, 2018
Request request,
int statusCode,
String message,
Exception e
) throws HaltException {
// Note that halting occurred, also print error stacktrace if applicable
if (e != null) e.printStackTrace();
LOG.info("Halting with status code {}", statusCode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@evansiroky, thanks for this change, but I was originally thinking that we would also log the message arg unconditionally as well (i.e., combining the log statement at line 115 with this log statement). I feel like logging just the statusCode leaves out some info that could be helpful in debugging.

Copy link
Member

@landonreed landonreed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@landonreed landonreed assigned evansiroky and unassigned landonreed Dec 19, 2018
@evansiroky
Copy link
Author

Message added to log statement.

@evansiroky evansiroky assigned landonreed and unassigned evansiroky Dec 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants