ryanb / letter_opener

Preview mail in the browser instead of sending.
MIT License
3.73k stars 238 forks source link

Disabling Launchy #173

Closed prdanelli closed 4 years ago

prdanelli commented 4 years ago

Hello,

First of all, thank you for the Gem, its super useful.

I am trying to move an app to Docker, but LetterOpener doesn't seem to want to let me disable Launchy. I've added an initializer as the docs recommend, trying to just nil the Launchy.application however that didn't seem to have any effect.

# config/initliazers/launchy.rb
Launchy.application = nil

I had a look through the code and couldn't see any way to disable it within the Gem, so I was wondering if you might consider adding a flag to disable that part of it. The ability to catch emails in development is amazing, but launching a web browser/tab is something that i'd love to suppress - and instead just view the email inside of the web interface.

As you can see from the error below, my Sidekiq container is trying to send the email via ActionMailer but a Launchy::CommandNotFoundError error is being thrown.


sidekiq_1        | 2020-03-08T14:06:19.376Z pid=199 tid=gt9iv5zkf class=ActionMailer::MailDeliveryJob jid=f98255d9285c047a82d8a325 elapsed=0.758 INFO: fail
sidekiq_1        | 2020-03-08T14:06:19.376Z pid=199 tid=gt9iv5zkf WARN: {"context":"Job raised exception","job":{"retry":true,"queue":"mailers","class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped":"ActionMailer::MailDeliveryJob","args":[{"job_class":"ActionMailer::MailDeliveryJob","job_id":"52048863-f20f-46ec-931e-73e299aeb18a","provider_job_id":null,"queue_name":"mailers","priority":null,"arguments":["ExportMailer","send_csv","deliver_now",{"args":[{"_aj_globalid":"gid://app/Export/4"}],"_aj_symbol_keys":["args"]}],"executions":0,"exception_executions":{},"locale":"en","timezone":"UTC","enqueued_at":"2020-03-08T14:06:18Z"}],"jid":"f98255d9285c047a82d8a325","created_at":1583676378.6154103,"enqueued_at":1583676378.6154485},"jobstr":"{\"retry\":true,\"queue\":\"mailers\",\"class\":\"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper\",\"wrapped\":\"ActionMailer::MailDeliveryJob\",\"args\":[{\"job_class\":\"ActionMailer::MailDeliveryJob\",\"job_id\":\"52048863-f20f-46ec-931e-73e299aeb18a\",\"provider_job_id\":null,\"queue_name\":\"mailers\",\"priority\":null,\"arguments\":[\"ExportMailer\",\"send_csv\",\"deliver_now\",{\"args\":[{\"_aj_globalid\":\"gid://app/Export/4\"}],\"_aj_symbol_keys\":[\"args\"]}],\"executions\":0,\"exception_executions\":{},\"locale\":\"en\",\"timezone\":\"UTC\",\"enqueued_at\":\"2020-03-08T14:06:18Z\"}],\"jid\":\"f98255d9285c047a82d8a325\",\"created_at\":1583676378.6154103,\"enqueued_at\":1583676378.6154485}"}
sidekiq_1        | 2020-03-08T14:06:19.377Z pid=199 tid=gt9iv5zkf WARN: Launchy::CommandNotFoundError: Unable to find a browser command. If this is unexpected, Please rerun with environment variable LAUNCHY_DEBUG=true or the '-d' commandline option and file a bug at https://github.com/copiousfreetime/launchy/issues/new
sidekiq_1        | 2020-03-08T14:06:19.377Z pid=199 tid=gt9iv5zkf WARN: /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy/applications/browser.rb:63:in `browser_cmdline'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy/applications/browser.rb:67:in `cmd_and_args'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy/applications/browser.rb:78:in `open'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy.rb:29:in `open'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/letter_opener-1.7.0/lib/letter_opener/delivery_method.rb:24:in `deliver!'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/mail-2.7.1/lib/mail/message.rb:2159:in `do_delivery'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/mail-2.7.1/lib/mail/message.rb:260:in `block in deliver'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/actionmailer-6.0.2.1/lib/action_mailer/base.rb:589:in `block in deliver_mail'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/notifications.rb:180:in `block in instrument'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/notifications.rb:180:in `instrument'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/actionmailer-6.0.2.1/lib/action_mailer/base.rb:587:in `deliver_mail'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/mail-2.7.1/lib/mail/message.rb:260:in `deliver'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/actionmailer-6.0.2.1/lib/action_mailer/message_delivery.rb:114:in `block in deliver_now'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/actionmailer-6.0.2.1/lib/action_mailer/rescuable.rb:17:in `handle_exceptions'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/actionmailer-6.0.2.1/lib/action_mailer/message_delivery.rb:113:in `deliver_now'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/actionmailer-6.0.2.1/lib/action_mailer/mail_delivery_job.rb:18:in `perform'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/execution.rb:39:in `block in perform_now'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:112:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/marginalia-1.8.0/lib/marginalia/railtie.rb:37:in `block (2 levels) in insert_into_active_job'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `instance_exec'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sentry-raven-2.13.0/lib/raven/integrations/rails/active_job.rb:13:in `block (2 levels) in included'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `instance_exec'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/i18n-1.8.2/lib/i18n.rb:313:in `with_locale'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/translation.rb:9:in `block (2 levels) in <module:Translation>'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `instance_exec'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/core_ext/time/zones.rb:66:in `use_zone'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/timezones.rb:9:in `block (2 levels) in <module:Timezones>'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `instance_exec'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/logging.rb:25:in `block (4 levels) in <module:Logging>'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/notifications.rb:180:in `block in instrument'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/notifications.rb:180:in `instrument'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/logging.rb:24:in `block (3 levels) in <module:Logging>'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/logging.rb:45:in `block in tag_logger'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/tagged_logging.rb:80:in `block in tagged'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/tagged_logging.rb:28:in `tagged'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/tagged_logging.rb:80:in `tagged'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/logging.rb:45:in `tag_logger'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/logging.rb:21:in `block (2 levels) in <module:Logging>'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `instance_exec'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:139:in `run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/execution.rb:38:in `perform_now'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/execution.rb:24:in `block in execute'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:112:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/railtie.rb:43:in `block (4 levels) in <class:Railtie>'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/execution_wrapper.rb:88:in `wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/reloader.rb:72:in `block in wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/execution_wrapper.rb:84:in `wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/reloader.rb:71:in `wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/railtie.rb:42:in `block (3 levels) in <class:Railtie>'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `instance_exec'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:139:in `run_callbacks'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/execution.rb:22:in `execute'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activejob-6.0.2.1/lib/active_job/queue_adapters/sidekiq_adapter.rb:42:in `perform'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:196:in `execute_job'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:164:in `block (2 levels) in process'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/middleware/chain.rb:138:in `block in invoke'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sentry-raven-2.13.0/lib/raven/integrations/sidekiq.rb:9:in `call'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/middleware/chain.rb:143:in `invoke'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:163:in `block in process'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/job_retry.rb:111:in `local'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/rails.rb:43:in `block in call'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/execution_wrapper.rb:88:in `wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/reloader.rb:72:in `block in wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/execution_wrapper.rb:88:in `wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/activesupport-6.0.2.1/lib/active_support/reloader.rb:71:in `wrap'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/rails.rb:42:in `call'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:257:in `stats'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/job_logger.rb:13:in `call'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/job_retry.rb:78:in `global'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:124:in `block in dispatch'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/logger.rb:10:in `with'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/job_logger.rb:33:in `prepare'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:123:in `dispatch'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:162:in `process'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:78:in `process_one'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/processor.rb:68:in `run'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/util.rb:15:in `watchdog'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/sidekiq-6.0.5/lib/sidekiq/util.rb:24:in `block in safe_thread'```

Sorry if there is another method that i'm missing. 

Thanks again,
Paul.
nashby commented 4 years ago

Hey @prwhitehead. Please see this discussion regarding this issue https://github.com/ryanb/letter_opener/issues/117. Hope it'll work for you!

prdanelli commented 4 years ago

Hey @nashby, Thank you for getting back to me.

Unfortunately, the recommendations in the thread you linked are to toggle the perform_deliveries flag, which then prevents all emails being sent so nothing shows up in Letter Opener.

config.action_mailer.perform_deliveries = false

The point I am trying to get to is where emails are sent by my app, they are caught by letter opener and available for me to see in the interface, but that the Launchy app isn't triggered to automatically open a new browser tab to present the new email.

Is this possible?

Thank you for your time, Paul.

nashby commented 4 years ago

@prwhitehead hey! Yeah, I think you can do it by simply setting ENV variable LAUNCHY_DRY_RUN=true. In this case Launchy will just output the command to stdout.

prdanelli commented 4 years ago

Hello @nashby, thank you for your response. Unfortunately, that didn't work. I am still getting the following error:

WARN: Launchy::CommandNotFoundError: Unable to find a browser command. If this is unexpected, Please rerun with environment variable LAUNCHY_DEBUG=true or the '-d' commandline option and file a bug at https://github.com/copiousfreetime/launchy/issues/new
sidekiq_1        | 2020-03-15T14:35:33.839Z pid=904 tid=gp9z4tfl8 WARN: /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy/applications/browser.rb:63:in `browser_cmdline'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy/applications/browser.rb:67:in `cmd_and_args'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy/applications/browser.rb:78:in `open'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/launchy-2.4.3/lib/launchy.rb:29:in `open'
sidekiq_1        | /usr/local/rvm/gems/ruby-2.6.5/gems/letter_opener-1.7.0/lib/letter_opener/delivery_method.rb:24:in `deliver!'

I confirmed that the ENV variable LAUNCHY_DRY_RUN was present by logging into the console and outputting the hash.

I did some googling and saw that another project seems to catch the error by monkey patching your delivery! method: https://github.com/fgrehm/letter_opener_web/blob/master/lib/letter_opener_web/delivery_method.rb

I would prefer not to monkey patch as it means future updates and bug fixes might be missed, but is this something that you would consider adding, in order to help users that are using docker for their apps - an increasing segment of the community i'm sure.

Thank you again for your help with this. Paul.

nashby commented 4 years ago

@prwhitehead Hey! Right, so as I can see Launchy just can't find any browser since you don't have any in your docker env. Could you please try to set BROWSER env to something like /dev/null (together with LAUNCHY_DRY_RUN=true)

prdanelli commented 4 years ago

OMG YES!

Thanks @nashby, thats working now. I get the following results:

sidekiq_1        | /dev/null file:////home/app/tmp/letter_opener/1584435709_1540718_673e21b/rich.html
sidekiq_1        | 2020-03-17T09:01:49.209Z pid=11 tid=gn1p1909v class=ActionMailer::MailDeliveryJob jid=7e439b8e0f7e89bebcddc8e8 elapsed=8.851 INFO: done

If I made a PR to edit the readme would you accept that, as it might be helpful for others as more move to dockerize their apps?

nashby commented 4 years ago

@prwhitehead awesome! Good idea about PR, go ahead, thanks!

danielsellergren commented 4 years ago

BROWSER=/dev/null LAUNCHY_DRY_RUN=true rails db:seed worked for me as well on a Rails 6 application without Docker.

fidalgo commented 3 years ago

Since I have an env var DOCKER_RUNNING, I can actually use something like: config.action_mailer.delivery_method = ENV['DOCKER_RUNNING'].present? ? :letter_opener_web :letter_opener