Seeing weird Parameters::ParseError in Rails 6 server logs - ruby-on-rails

Lately I'm seeing several ActionDispatch::Http::Parameters::ParseError in the logs every day. They weren't there before, and they affect several different POST requests, so I'm wondering if this is a bug related to a gem update or if it's just a new spammer attempt. The problem is made worse because I cannot tell why these requests are yielding ParseErrors.
Here are three examples from our donation page - I've anonymized the email addresses of course and I'd appreciate your help:
ActionDispatch::Http::Parameters::ParseError (859: unexpected token at 'authenticity_token=TW9l2RjJ3ColCnZ7FP%2F8Aqt0y%2FNYd2MR9F2JWADEL%2BejCvWtW1f2uPbcHTtEu0LzWwW11SWONsPz9FK8WcTKeA%3D%3D&stripeToken=&donation%5Bamount%5D=&donate-amount=other&donation%5Brecurring%5D=false&donation%5Bemail%5D=email%40comcast.net&commit=Pay+with+card')
ActionDispatch::Http::Parameters::ParseError (859: unexpected token at 'authenticity_token=zHcwkUforZ3JIbJgCjIecgdxbzk%2F93bHimmN1efHNIgoxaSsMJOMRqtDUENB62S4LoltNCiA8q1aP%2B%2FXWGXJ8A%3D%3D&user%5Bemail%5D=email%40okcattlemen.org&user%5Bpassword%5D=HJdwgFSVljOt%21&user%5Bremember_me%5D=1&commit=Sign+in')
ActionDispatch::Http::Parameters::ParseError (859: unexpected token at 'authenticity_token=dXDEHscUOuQMfP%2BDf2RKQM6SZIL666kzU80x5ewPOA6OYAN3OzvIizWGQy4SOSjd7NTTRE1P4%2FO8%2BQSpJLa9Wg%3D%3D&stripeToken=&donation%5Bamount%5D=&donate-amount=other&donation%5Brecurring%5D=false&donation%5Bemail%5D=email%40gmail.com&commit=Pay+with+card')
The trace shows this error being thrown by actionpack (6.0.0) lib/action_dispatch/http/parameters.rb:115:in rescue in parse_formatted_parameters
What part of this cannot be parsed? Would it have natural or unnatural causes? Any hints would be useful.

Related

Rails server returning HTTP status 0

I understand that sometimes a client will show an HTTP request as returning a 0 status code when the request fails to connect, timesout, etc, but I have never seen a server logging 0 as what it is sending back to the client.
I am running a Rails 4.2, ruby 2.2.x API. I was analyzing our logs the other day and noticed that a non-trivial number of requests were being responded with an HTTP status code of 0 by our Rails API. I have been unable to figure out why.
In some cases, it appears the request never makes it to the rails app. I only see the log message which I believe is logged by rack as to the request path and status returned. In other cases, I can see one of the early log messages we log from our application controller.
Has anyone seen such a behavior? I am not sure how to debug further without beginning to modify the standard rack middlewares that rails provides. I am not able to reproduce the situation myself; I only see this sporadically in our logs.
A bit more about our stack:
Rails 4.2.5
Ruby 2.2.3
Puma 3.4.0
We are reverse proxying with nginx, but I dont think is effecting it since the request is received by rack at least.
I realize it would probably be impossible to answer what exactly is happening here, so I am hoping instead for suggestions on how best to troubleshoot this.
Found that this is an issue with our Rails logging setup. By correlating these logs to our nginx access logs, I can see that a 302 is actually being returned to the client. This was commonly happening when the CSRF protection failed.
It looks like this is caused by a lograge (gem) bug: https://github.com/roidrage/lograge/issues/67
I have seen this behavior when requests were sent from different subdomains that were not allowed based on Access-Control-Allow-Origin. So maybe that's one possibility

Rescue from errors for end-users, but email me error details (Rails)

What what is a best practice around gracefully handling (i.e. begin...rescue...end) errors for end-users, yet alerting me that they are happening?
More details:
I have a Ruby on Rails web application whose core functionality relies on several APIs (as well as some web scraping), so I need to be extra careful with handling API errors that may occur. Examples of said errors: Exceeding API concurrent usage limits, API data coming back in a format I didn't expect, web scraping gone awry, etc.
I'd like for end users to not have a bad experience if APIs falter for any of those reasons. Here's my current setup, and I'd love to know if this is a best practice, or I'm missing anything big:
Currently, I use the very helpful exception_notification gem to email me errors.
For any API I use, I create a wrapper class in my app's /lib directory, and within that class I clean up what the API returns (basically just to standardize it for my needs). It's within these wrapper classes that I have begin...rescue blocks, like so:
begin
# the API call, or scrape with Nokogiri here...
rescue Errno::ECONNREFUSED, Zlib::DataError, RuntimeError, OpenURI::HTTPError => e
# set the return value to a helpful error or something...
end
As you can see, I'm rescuing from 4 different exceptions here, and the only way I'm discovering those is through trial and error.
Problem one: The rescue made it so the end user's experience wasn't jarring, but I have no way of knowing that an API (or scrape) went badly, so I'm thinking I should use exception_notification's manual sending of a notification to just email myself the exception in the rescue block. Is this a decent way of handling this?
Problem two: More than just those 4 specific exceptions might happen. Should I save myself the guesswork and just rescue from Exception => e, and email myself whatever e is?
Thanks!
SOLUTION
Rather than using exception_notification to email exceptions to myself in the rescue block, I went with Anthony's advice in the comments and started using Rollbar.
Regarding the issue of which exceptions to rescue from, it's a better idea to Rescue StandardError, Not Exception.

Asana returns spurious 500 errors with cryptic messages

I am seeing spurious HTTP 500 errors with cryptic messages. For example, doing a GET using oauth on /projects/28408740055707 I see a response body: {"errors":[{"message":"Server Error","phrase":"24 purple woodchucks wriggle fast"}]}
I've also seen it on GET /tasks/{taskId}/stories and other endpoints as well. Any thoughts on this? Thanks!
When an API call or an action within the Asana application generates a server error we generate a random phrase that corresponds so that we can easily look up logs about the issue later.
If you continue to experience 500 errors when making calls to the API we encourage you to write into api-support#asana.com and reference the error phrase along with the call that you were making so that we can try to fix the issue.
I checked for "24 purple woodchucks wriggle fast" and that specific issue seems to have been solved.

How to ignore routing error with wrong verb

I have a few POST actions. There are always stupid crawlers trying to ping those actions, resulting in "No route matches [GET]" errors.
There are too much of them, and most of them are purely noise. How can I make it so this kind of error messages are ignored.
I used to use exception_notification gem, and now I use rollbar gem. The amount of these kind of trash error message always floods my error monitoring (either lots of messages, or too much error api calls).

Rails Production Enviornment errors submit via email

I have a Rails 3.2.14 app in production that as designed when an exception is raised, I get the 500 page "Something went wrong". When this happens, an employee will usually call me right away and tell me that an error occurred but this is not always the case. Sometimes I won't know about the error in production until later that day or longer.
What I'd like to do is set up my production environment to where when an exception/error is raised it displays and error page, but sends me an email in the background.
I've done some research and I see there's AirBrake, but I'm really looking to build/implement my own solution instead of paying for a 3rd-party service.
Can anyone suggest a gem or snippet of code that emails when an error/exception is raised and/or gives the end-user the option to submit the error from the 500 page?
The exception notification does exactly this.
You might also be interested in errbit. It implements the same api as airbrake - in a nutshell you'd be hosting your own version of airbrake.

Resources