Padrino send errors automatically via email - ruby

Can anyone suggest a way to have any application errors in a Padrino app send these errors via email?
I already have the Padrino Mailer configured properly and can send test emails, I just have no idea how to configure the app to send me a report via mail (as well as logging it, of course) whenever an error occurs.
Thanks.

I ended up using the padrino-contrib gem. With it, you can install the plugin you need (of course you can do it manually also):
padrino-gen plugin exception_notifier
Which will add it to your gem file and also edit your app/app.rb and boot.rb files to load this gem.
Then in app/app.rb you put something like:
register Padrino::Contrib::ExceptionNotifier
set :exceptions_from, "noreply#domain.com"
set :exceptions_to, "your_address.domain.com"
And that's it.
The nice thing about letting the plugin install it for you is that if you're more familiar with Rails than Padrino (as is my case) this will not only set things up for you, but also show you were the directives need to go.
Hope this helps someone else.

A good approach should be using exception handlers. Adding a begin..rescue block to your code, and if there is an exception, you send the email and continue to the desired behavior.
def some_action
begin
# some code that could go wrong
rescue SomeExceptionClass => some_variable
# here you send the email with the errors
# render stuff, redirect stuff, etc
end
end

Related

jRuby Test Automation: Checking to see that an email has been sent. What libraries are available?

Background
I'm doing jRuby tests for a Grails app that sends emails. These tests are replacing tests that are normally done by manual testers. They check their inboxes to see that mail has been delivered.
Problem Statement
I want to do a similarly strong test that ensures the email is sent properly by the app.
I do not need any actual code to help do this necessarily, but it would help to know what technologies to use.
Why I've Been Stumped So Far
I've looked for solutions in the Ruby domain, but everybody that I've seen address this problem seems to be using Rails. I am not using action_mailer or pony (we have a grails app) so I can't use email_spec. If I could that would be great.
What can I do?
You can use the Rails approach to testing mails: monkey-patch mail send code during test setup to place all mail instances that should have been delivered into a globally accessible array, this way you can do asserts on that array.
Don't ask me for exact implementation details because I'm not into grails, but the general principle is this:
if you have a class MyMailThingy which has a deliver method on it's instance which performs the mail delivery (presumably mail subject, body etc are attributes on this object), then monkey patch:
class MyMailThingy
# same as `cattr_accessor :mock_queue` under rails
def self.mock_queue; ##mock_queue; end
def self.mock_queue=(arg); ##mock_queue=arg; end
def deliver
self.class.mock_queue ||= []
self.class.mock_queue << self.dup
self
end
end
and then in your tests you can assert on MyMailThingy.mock_queue how many mails have been sent, assert on their bodies, subjects, to/from fields etc without sending actual mails
I found an answer on how to send the mail here. It seems like Ruby has built in support for SMTP. I am looking at how to check the mail now.

Open mail client from cli ruby script like a mailto link

I have written a ruby cli script which takes a CSV and generates a PDF report, based on said CSV. I'm fairly new to Ruby, so while it's probably not the greatest code, I'm pretty proud of what I've made.
At any rate, what I would really like to do now, is make my script email said PDF as an attachment. I'm sure there is a library that understands SMTP and can send this on my behalf, but I would like to modify the email body, and review the attachments before sending. So it seems like the simplest thing would be to have the script start a new email in my system default mail client, providing the recipient, subject, and boiler plate text, and attaching the generated file, kind of like a mailto: link in a web page (does mailto support attachments?).
Seems like there could be a system command that does this, completely unrelated to Ruby, which I could have my Ruby script call. That would be fine. If it's platform dependent, I'm on OSX, but I move around, so am interested in Windows and Linux solutions, too.
I guess plan B would be a way to jam a simple CLI editor into my Ruby script, to let me edit the email text, and then use an SMTP library to send the email. That seems harder, unless it's already been done.
Actually you can execute any ruby file from command-line interface (CLI) using console_runner gem. If you already have written code you can run it from command line. All you need is to add annotations (YARD-like syntax) to your Ruby code and then execute it from command line:
$ c_run /path/your_file.rb say_hello
/path/your_file.rb:
# #runnable
class MyClass
# #runnable
def say_hello
puts 'Hello!'
end
end

How should I test Mailman app

I'm trying to write some specs for my application aimed to process and resend incoming emails. It's built with Mailman App. I didn't find any good examples on how to do that. What am I actually trying is to create email (with Mail gem) and process it with Mailman. But there is only option of using stding for testing.
So, are there any examples of specs written to test the mailman apps?
I think it is useful to extract as much as possible out of your Mailman::Application block and put it into your app somewhere. Then test that processing.
This Railscast (pro-only, sorry) has an example of "An Alternative to Routing" that is pretty good.
Basically instead of doing something like:
Mailman::Application.run do
subject(/Update (\d+)/) do |ticket_id|
...
you just say:
Mailman::Application.run do
default do
MailProcessor.receive_mail(message)
end
end
Then the MailProcessor class would handle reading the message and calling the right other functions in your app (depending on the message's subject, recipient, sender, etc.) I would then RSpec test the MailProcessor class for doing the right thing.
This is similar to how I approach testing rake tasks (put the functionality in a lib file that you test, and have the rake task just call the lib file.) Then you can be fairly certain that the functionality is being tested properly. If you were paranoid about the rake task, you can try an approach like: http://robots.thoughtbot.com/post/11957424161/test-rake-tasks-like-a-boss.

Intercept every exception in Ruby

I used exception_notifier gem and Airbrake, but I would like to intercept and send the error, environment and backtrace to a web service. I think I should monkey patch Object::Exception but I am not sure how. I do not want to change the behaviour of Object::Exception but just intercept and send its data. I would like to do it for any Ruby app, so I would like an agnostic solution. If it is not possible a framework-agnostic solution, a Rails solution is better than nothing, but I guess I could study the exception_notification gem.
For Rails, you can put the following in application_controller.rb:
rescue_from Exception do |e|
# do whatever you want with the exception
# and if you still want the exception to continue propagating, then:
raise e
end

Ruby: Get currently logged in user on windows

In C# I can get the current user of a web app using the HttpContext, however, I can't figure out how to do this in Ruby. Is there any way of doing this?
FOR THOSE OF YOU SAYING IT IS IMPOSSIBLE, HERES PROOF:
http://www.codeproject.com/KB/aspnet/How_to_NT_User_Name.aspx
Well, to get the current username, there's this:
puts ENV['USERNAME']
Or go to the Win32API.
require 'dl/win32'
def get_user_name
api = Win32API.new(
'advapi32.dll',
'GetUserName',
'PP',
'i'
)
buf = "\0" * 512
len = [512].pack('L')
api.call(buf,len)
buf[0..(len.unpack('L')[0])]
end
puts get_user_name
Edit: And I'm an idiot. This isn't what you asked for at all. Oh well, it took me time to dig this out of my code, so it might as well stay here for anyone else wondering :P
Edit again: OK, it turns out I'm not an idiot after all. This is what you want. When I went back and re-read your question, the HttpContext threw me off, and I thought it was the current username from HTTP auth or something.
To get the username of the current user on client machine you can use this
ENV['USERNAME']
If you're using Rails try: request.env['HTTP_REMOTE_USER']
I think what you mean is how you can retrieve the username that the user used to login to the web application. That will differ depending on what authentication mechanism you're using. Some Apache authentication modules, for example, will pass REMOTE_USER (e.g. the Kerberos module), the CAS Single-Sign-On module passes CAS-USER, etc. Standard digest authentication and such uses the Authentication header. You should be able to access these using request.env[HEADER] as someone else pointed out above. Check out the documentation on how your authentication layer is passing on the user in the HTTP request.
Is your c# code running as a .NET plugin/client-side code or is it ENTIRELY server side? Your ruby code would be entirely server side. According to the MS docs, only stuff running in the CLR sandbox can really get to that information:
http://msdn.microsoft.com/en-us/magazine/cc163700.aspx (under Defining the sandbox).
One thing interesting to note is that sites registered under LocalIntranet have access to that information. I'm not sure off hand how this maps to security zones in IE though.
The thing to understand is that LOGON_USER is NOT visible to the browser sandbox anymore than the browser can see the contents of a filesystem path on your system. The fact that your c# code sees it almost certainly indicitive of some clientside component passing it upstream.
You have the option of implementing mod_ntlm under apache and pushing the headers downstream. I don't have the points to post a second link but google 'rails ntlm sso' and see the rayapps.com link.
but if your app isn't Rails based, you'll have to port that to your server code. You can also checkout rack-ntlm if your app is rack compliant.
[RUBY ON RAILS ONLY]
This is what worked for me but there are some limitations:
won't work in Chrome: undefined method 'encode' for nil:NilClass
won't validate user credentials
If you don't care about these issues, go ahead:
In your rails application, add Rekado's gem to your Gemfile: gem 'ntlm-sso', '=0.0.1'
Create an initialiser config/initializers/ntlm-sso.rb with:
require 'rack'
require 'rack/auth/ntlm-sso'
class NTLMAuthentication
def initialize(app)
#app = app
end
def call(env)
auth = Rack::Auth::NTLMSSO.new(#app)
return auth.call(env)
end
end
On your application.rb file, add the line: config.middleware.use "NTLMAuthentication"
Call request.env["REMOTE_USER"] on your view or controller to get current username.
PS: Let me know if you find anyway to make it work on Chrome or to validate user credentials.

Resources