Honeybadger on localhost with Ruby on Rails - ruby-on-rails

I've set up Honeybadger almost a year ago and so far it works like a charm registering errors on my production and staging environments.
Then I decided to make a custom error behavior in controller. I am using the code similar to:
begin
params = {
:id => 1,
:class => MyClass,
:foo => "bar"
}
my_unpredicable_method(*params)
rescue => e
Honeybadger.notify(
:error_class => "Special Error",
:error_message => "Special Error: #{e.message}",
:parameters => params
)
end
which is described here.
I was going to test in local environmet to tune error messages, passing params, etc.
But the problem is when I receive the error (I am sure that I receive it, tested with debugger) nothing is sent to honeybadger website. Meanwhile, rake honeybadger:test works fine and sends the testing error messages to the server from localhost. Also, this custom notification works if I push it to testing environment on Heroku.
The question is:
What should I do to send this custom error to honeybadger from localhost?
Thank you in advance.

I found a solution. We need to add the following option to honeybadger initializer:
config.development_environments = %w(test)
This option is the list of environments in which notifications should not be sent and by default development in the list. See detailed explanation of the configuring option here.

Please add following configuration in config/honeybadger.yml
development:
report_data: true
Please read https://github.com/honeybadger-io/honeybadger-ruby#configuration-options

Related

Json API Curl to HTTParty request. The request works on my local machine with cURL, but not in Heroku production with HTTParty

So, I've gotten to the point that I'm not sure what question to ask anymore when researching my issue. So by coming here, I'm asking 2 things.
First, how do I got about investigating issues like this in the future?
Second, what am I doing wrong right now?
Basically, I created an app and pushed it to Heroku. This app has API endpoints that work exactly as I expect them to when I am running the app locally and sending curl commands through my terminal. The code I'm running to try to sign-in to my app uses the HTTP gem and is returning {"status":500,"error":"Internal Server Error"}.
So, this is my first time trying to connect to any API endpoint, so I'm flying a bit in the dark here. What I read about a 500 error is, "When all else fails; generally, a 500 response is used when processing fails due to unanticipated circumstances on the server side, which causes the server to error out." Which sounds a bit like a catch-all for somethings broken but we don't know what, other than it's on the backend. Please correct me if I'm wrong.
What do I do next?
This is the curl command I'm running to send an email and password to receive and auth_token:
curl -d "user_login[email]=fake#email.com&user_login[password]=password123" http://localhost:3000/api/v1/sign-in
As expected I get this back:
{"auth_token":"628f3ebc47193665e7f1d32ae41ff9a7"}%
This is the code I'm running using HTTParty to try and connect with my API in production using Heroku:
consume_api.rb
require "rubygems"
require "httparty"
query_hash = { :user_login => "fake#email.com",
:password => "password123" }
response = HTTParty.post("https://fake-heroku-94488.herokuapp.com/api/v1/sign-in", :query => query_hash)
puts response.body, response.code, response.message, response.headers.inspect
This is the response back:
{"status":500,"error":"Internal Server Error"}
500
Internal Server Error
{"server"=>["Cowboy"], "date"=>["Fri, 03 Feb 2017 14:49:40 GMT"], "connection"=>["close"], "content-type"=>["application/vnd.api+json; charset=utf-8"], "x-request-id"=>["5d094cee-11a2-4040-abfd-5180f5e46886"], "x-runtime"=>["0.003503"], "vary"=>["Origin"], "content-length"=>["46"], "via"=>["1.1 vegur"]}
To reiterate my questions are what can I take from this response to start investigating further? What questions should I be asking myself when this happens?
Second, What did I do wrong?
Thanks in advance for your help.
Edit:
A quick update is that I ran the curl command that worked locally with the actual URL for my production site and it worked exactly as it does locally. I still can't manage to get further using HTTParty.
I checked out my heroku logs and found this:
2017-02-03T17:22:26.576272+00:00 heroku[router]: at=info method=POST path="/api/v1/sign-in" host=fake-heroku-94488.herokuapp.com request_id=9ab76ce0-95f3-4479-8672-874a624c070e fwd="108.11.195.58" dyno=web.1 connect=1ms service=8ms status=500 bytes=265
Started POST "/api/v1/sign-in" for 108.11.195.58 at 2017-02-03 17:22:26 +0000
Processing by Api::V1::SessionsController#create as JSON
Parameters: {"email"=>"fake#email.com", "password"=>"[FILTERED]"}
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `[]' for nil:NilClass):
app/controllers/api/v1/sessions_controller.rb:7:in `create'
Which points to line 7 of my SessionsController:
...
6 def create
7 resource = User.find_for_database_authentication(:email => params[:user_login][:email])
8 return invalid_login_attempt unless resource
...
Line 7 has two arrays in it, but I'm not sure how they're empty in the Httpary request and just find in the curl request.
The answer to my first question of what I should do if I bump into this issue or one like it again is to check out the Heroku logs. That started the unwinding of my problems. The second part of this answer is that even when I figured out that I wasn't sending in the :user_login info, I still couldn't figure out how to fix my issue, so I started dropping byebug into anyplace related to my issue and asking what my variables values were and running code to see the output in console. When they kept coming back nil and I couldn't figure out what the right order/way to right the HTTParty request, I started putting .methods or .instance_methods after my variables to find more ways to ask what is going on here. After that I spent time in rails console, using whatever instance_methods that were associated with my variables until I put the pieces together.
The answer to my second question, what was I doing wrong? I wasn't sending in :user_login, mainly because I didn't quite understand what it was supposed to be doing (I'm new, I use a lot of tutorials that I understand like 95% of, this was from the 5%) and even when I did, I couldn't figure out how to shove it in my request. As it turns out, I also wasn't using :body appropriatly. Once I figure out that I need to put :body around all of the data that I was sending in, my next layer was :user_login then followed by my :email and :password, which with hindsight looks perfectly obvious now.
This is what the code to sign in to my app looks like:
consume_api.rb
require "rubygems"
require "httparty"
response = HTTParty.post("https://fake-heroku-94488.herokuapp.com/api/v1/sign-in", :body => {:user_login => {:email => "fake#email.com", :password => "password123"}})
puts response.body, response.code, response.message, response.headers.inspect

Pusher Heroku Add-on error

so I'm using the Pusher Heroku Add-on for my application. The application has live notifications, so when a user receives a message he will see a pop up notification saying "new message". However, In production I am getting the below error:
Firefox can't establish a connection to the server at ws://ws.pusherapp.com/app/b1cc5d4f400faddcb40b?protocol=7&client=js&version=2.1.6&flash=false.
Reload the page to get source for: http://js.pusher.com/2.1/pusher.min.js
And here's the Pusher controller:
class PusherController < ApplicationController
protect_from_forgery :except => :auth # stop rails CSRF protection for this action
def auth
Pusher.app_id = ENV['PUSHER_APP_ID']
Pusher.key = ENV['PUSHER_KEY']
Pusher.secret = ENV['PUSHER_SECRET']
if current_user && params[:channel_name] == "private-user-#{current_user.id}"
response = Pusher[params[:channel_name]].authenticate(params[:socket_id])
render :json => response
else
render :text => "Not authorized", :status => '403'
end
end
end
And I'm using the figaro gem to push the keys to heroku.
What am I doing wrong?
Kind regards
JS
That looks like a problem with Javascript, rather than Rails
We've got pusher working very well with one of our production apps, and it works by firstly having the pusher gem installed, allowing you to call the pusher JS files from your layout:
#app/views/layouts/application.html.erb
<%= javascript_include_tag "http://js.pusher.com/2.1/pusher.min.js" %>
Rails
You may also wish to put the pusher initialization code into an initializer:
#config/initializers/pusher.rb
Pusher.url = ENV["PUSHER_URL"]
Pusher.app_id = ENV["PUSHER_APP_ID"]
Pusher.key = ENV["PUSHER_KEY"]
Pusher.secret = ENV["PUSHER_SECRET"]
This will ensure app-wide connectivity, rather than controller-specific (allowing for greater flexibility)
Firefox can't establish a connection to the server at ws://ws.pusherapp.com/app/b1cc5d4f400faddcb40b?protocol=7&client=js&version=2.1.6&flash=false.
Reload the page to get source for: http://js.pusher.com/2.1/pusher.min.js
This doesn't necessarily mean anything is wrong. it just means that an unsecured WebSocket connection couldn't be established. Pusher's fallback strategy should result in a successful connection being established via either HTTP fallback (HTTP or HTTPS) or via WSS (a secure WebSocket connection).
Failed connection attempts are logged as console errors. There's nothing that can be done about that.
To test this you can bind to connection events and ensure that you are indeed connecting. The pusher-js JavaScript logging will also help determine what's happening.
You can also try http://test.pusher.com/

Faye on Heroku: Cross-Domain Issues

I'm currently hosting both my rails app and a faye-server app on Heroku. The faye server has been cloned from here (https://github.com/ntenisOT/Faye-Heroku-Cedar) and seems to be running correctly. I have disabled websockets, as they are not supported on Heroku. Despite the claim on Faye's site that:
"Faye clients and servers transparently support cross-domain communication, so your client can connect to a server on any domain you like without further configuration."
I am still running into this error when I try to post to a faye channel:
XMLHttpRequest cannot load http://MYFAYESERVER.herokuapp.com. Origin http://MYAPPURL.herokuapp.com is not allowed by Access-Control-Allow-Origin.
I have read about CORS and tried implementing some solutions outlined here: http://www.tsheffler.com/blog/?p=428 but have so far had no luck. I'd love to hear from someone who:
1) Has a rails app hosted on Heroku
2) Has a faye server hosted on Heroku
3) Has the two of them successfully communicating with each other!
Thanks so much.
I just got my faye and rails apps hosted on heroku communicating within the past hour or so... here are my observations:
Make sure your FAYE_TOKEN is set on all of your servers if you're using an env variable.
Disable websockets, which you've already done... client.disable(...) didn't work for me, I used Faye.Transport.WebSocket.isUsable = function(_,c) { c(false) } instead.
This may or may not apply to you, but was the hardest thing to track down for me... in my dev environment, the port my application is running on will be tacked onto the end of the specified hostname for my faye server... but this appeared to cause a failure to communicate in production. I worked around that by creating a broadcast_server_uri method in application_controller.rb that handles inclusion of a port when necessary, and then use that anywhere I spin up a new channel.
....
class ApplicationController < ActionController::Base
def broadcast_server
if request.port.to_i != 80
"http://my-faye-server.herokuapp.com:80/faye"
else
"http://my-faye-server.herokuapp.com/faye"
end
end
helper_method :broadcast_server
def broadcast_message(channel, data)
message = { :ext => {:auth_token => FAYE_TOKEN}, :channel => channel, :data => data}
uri = URI.parse(broadcast_server)
Net::HTTP.post_form(uri, :message => message.to_json)
end
end
And in my app javascript, including
<script>
var broadcast_server = "<%= broadcast_server %>"
var faye;
$(function() {
faye = new Faye.Client(broadcast_server);
faye.setHeader('Access-Control-Allow-Origin', '*');
faye.connect();
Faye.Transport.WebSocket.isUsable = function(_,c) { c(false) }
// spin off your subscriptions here
});
</script>
FWIW, I wouldn't stress about setting Access-Control-Allow-Origin as it doesn't seem to be making a difference either way - I see XMLHttpRequest cannot load http://... regardless, but this should still works well enough to get you unblocked. (although I'd love to learn of a cleaner solution...)
Can't say I have used Rails/Faye on Heroku but have you tried setting the Access-Control-Allow-Origin header to something like Access-Control-Allow-Origin: your-domain.com?
For testing you could also do Access-Control-Allow-Origin: * to see if that helps
Custom headers
Some services require the use of additional HTTP headers to connect to
their Bayeux server. You can add these headers using the setHeader()
method, and they will be sent if the underlying transport supports
user-defined headers (currently long-polling only).
client.setHeader('Authorization', 'OAuth abcd-1234');
Source: http://faye.jcoglan.com/browser.html
So try client.setHeader('Access-Control-Allow-Origin', '*');

Rails: OAuth2 gem returns 400 error when attempting to connect to facebook

I'm attempting to add Facebook connect to our web app, and I'm running into a problem with. Everything works fine locally (I can authenticate through Facebook), but when I push the code to our dev server (which lives in the wild), every time I try to authenticate it returns the following error code:
OAuth2::HTTPError: Received HTTP 400 during request
That's really the only explanation I'm getting. Again, this works on my local machine, and the gems and such match between boxes, so I'm a bit confused. Here's the code I'm executing.
def facebook_connect
#Set the scope we want to pull from Facebook, along with the callback URL
options = {
:redirect_uri => facebook_callback_url,
:scope => "email,publish_stream"
}
#Go out and fetch the url
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Redirect to the callback for processing
redirect_to client.web_server.authorize_url(options)
end
def facebook_callback
#Client URL
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Parse out the access token
access_token = client.web_server.get_access_token(params[:code], :redirect_uri => facebook_callback_url)
#Get the user
fb_user = JSON.parse(access_token.get('/me'))
#Do some authentication database stuff
end
def facebook_callback_url
uri = URI.parse(request.url)
uri.path = '/users/facebook_callback'
uri.query = nil
uri.to_s
end
I searched Google, but the solutions that show up aren't working. Also, if anyone knows how to parse and display OAuth2 errors, I would appreciate that, as well. Thanks
Assuming that Facebook OATH knows of your server's IP address(they are very strict about it), I would recommend that you use use 'rescue' to catch that exception, get the backtrace and then find where it is being raised and place a bunch of debug statements to check the state of both request and the response, as well as access tokens.
Or you can configure remote debugging with Rubymine or NetBeans which is not an easy task :)
The issue actually ended up being a problem with the "Faraday" gem. Our dev server wasn't set up to handle SSL, which was returning an error code. We patched it using the following answer:
OmniAuth & Facebook: certificate verify failed

Rails app using Oauth to post to Twitter, getting "not authorized" when running in production server. OK in localhost

I'm trying to use Twitter's Oauth Single Token for posting from a rails app to my twitter feed (single user use-case is perfect for my app). This Is what I'm talking about.
Here's the relevant part of my code:
twitter_consumer_key = 'AAAAAA...'
twitter_consumer_secret = 'BBBBBB///'
oauth_token = 'CCCCC....'
oauth_token_secret = 'DDD.....'
consumer = OAuth::Consumer.new(twitter_consumer_key, twitter_consumer_secret, :site => "http://api.twitter.com", :scheme => :header)
access_token = OAuth::AccessToken.from_hash(consumer, :oauth_token => oauth_token, :oauth_token_secret => oauth_token_secret)
response = access_token.post("http://api.twitter.com/1/statuses/update.json", {:status => "Coffee's ready at 191 Peachtree!! "+Time.now.to_i.to_s})
logger.info response.inspect
When I run this in my local machine, everything goes well and the post is created on my feed. When I run it on my production server (centos5.5, Apache 2, Passenger, Rails 3.0.4) I get "HTTPUnauthorized".
Any ideas on how to troubleshoot this?
Thanks in advance.
Try with filling Callback URL in settings of your application on dev.twitter.com.
Should be something like that:
Callback URL http://yousite.com/auth/twitter/callback
Per abraham's comment, I'm adding the solution as an answer instead of a comment:
My server's timezone was incorrectly set so I was getting the following error in the response body:
{"request":"\/1\/statuses\/update.json","error":"Timestamp out of bounds"}
I set the time and timezone correctly and now it's working fine.
:)

Resources