How can I stop Rails execution from initializer? - ruby-on-rails

I want to stop the app start up from an initializer.
Something like if a config isn't present, stop server/console, etc.
Also send a message in order to explain the error.
Is there a way to do that?
I looked into initialization events but I cannot make it happen.
Thanks in advance.

Yeah, just raise an exception like you normally would:
raise StandardError, "Stopping app start up because something is missing"
If you're doing this because some config is missing, consider using something like Figaro which does this for you.
Figaro.require_keys("pusher_app_id", "pusher_key", "pusher_secret")
https://github.com/laserlemon/figaro

You can use the Kernel#abort method to do it. It'll stop the application with your provided message and won't throw up any error.
Example:
abort('You need to pass more info to start the application') if some_check_fails?

Related

Starting Byebug with a block

I'm wondering if it's possible to start a Byebug session giving a starting point from a Rails console. I know I can insert a byebug statement wherever I want and start debugging, but I'd like to do something like this:
Byebug.start do
# entry point
User.find(12).problematic_method
end
Thanks.
I opened the class and override the problematic_method inside the Rails console and added the byebug statement where I wanted it. This way I don't have to change the running production code (I forgot to mention above I want to debug in production).
This workaround will be enough for my purposes. The only problem is that you don't have the debug code listing available for that method, but its fine.
That is not possible. What you can do, is write your code inside a .rb file and debug that file/script using byebug.

Make Byebug finish executing without exiting Pry

When I set a breakpoint with Byebug in Rails, I sometimes want it to finish executing, but the guide on github says to use exit which also exits Pry. Typing continue repeatedly can be annoying if the breakpoint is in a loop.
Is there anyway to stop byebug without exiting the Rails console?
When running byebug under the Rails console or in Rails' server I usually quit only byebug by hitting Ctrl+D.
The catch with this approach is, if you do this in Rails' server then Byebug will not stop and debug the next time it hits a byebug statement in your code anywhere. But it works perfectly in the Rails console.
Try !!!. It works on pry gem, but not sure if it does on byebug.
Well this isn't the most elegant solution but it works for me so far.
If you have a base controller in your rails application you can add an accessor to hold a variable saying whether you want debugging to happen or not:
attr_accessor :debugging
Then add/modify initializer to set the variable to true on each request (or each time there is an instance created for that object):
def initialize
#debugging=true
super
end
And finally, always use the byebug call with a conditional wherever you want this behavior:
byebug if debugging
Then when you are at the IRB console and you want to exit the debugger but continue executing the code you just set the variable:
#debugging=false; finish
You could even encapsulate this in a helper or do some OOP magic but this is a good starting point. Nice thing is that if you repeat the request you'll get the standard behavior again unless you set the variable to false again.
If you want to exit a loop try skip.
It'll runs until the next breakpoint as long as it is different from the current one.
Then, once you are out of the loop you can continue.
Typing finish in the console exits byebug, without closing pry/rails console/rails server.
Ctrl + D also works.
Go to your code and remove byebug and save, then in the buybug terminal write continue then press enter.
Tadaaa your app will continue and you will exit byebug all without closing your app.
Try continue or finish
Source: https://edgeguides.rubyonrails.org/debugging_rails_applications.html#resuming-execution
Remove "debugger from your code and type in "finish" in console
(byebug) quit
Really quit? (y/n) y
user ~
The only one that works quickly and without issues for me so far.

Customize exception_notifier, Ruby on Rails

I have successfully added the exception_notifier to my rails app, and it is emailing a notification for all exceptions at the application level (which is exactly what I want). The only problem is that I need to have a few short lines of code ran whenever an exception is raised as well, and am certain that there is a way to add these lines of code onto the notifier. But despite reading the documentation found here: https://github.com/smartinez87/exception_notification I am still unclear what/where I should put things. Can someone please explain this a bit better for me. I am relatively new to ROR. I just need to add some additional code to run whenever the notifier is alerted to an exception.
This seems to be the correct link to the background notification:
Using a begin rescue should do the trick.
def method
sentence1
begin
sentence2
sentence3
rescue => e
ExceptionNotifier.notify_exception(e)
Sentence code1
return action
end
end
As explained here:
https://github.com/smartinez87/exception_notification#background-notifications
So as a shorthand: To do code before or after the notification is sended, but outside of the notification method you need to catch the exception in the method who raised it and work there.
But remember: Catching exceptions should be an exception. If you know what could go wrong, try to fix it, not to catch it.

Logging all method calls in a Rails app

Is there an easy way to log all method calls in a Rails app?
My main use for this would be in testing (and in debugging tests). I want to have more of a history than a stacktrace provides (for instance, when running rspec with the '-b' option).
It's easy to do. Just add 5 lines of code into your script/server:
#!/usr/bin/env ruby
set_trace_func proc {
|event, file, line, id, binding, classname|
if event == "call" or event == "return"
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
end
}
require File.expand_path('../../config/boot', __FILE__)
require 'commands/server'
It's described at http://phrogz.net/ProgrammingRuby/ospace.html#tracingyourprogramsexecution
Your application will become quite slow and you might get more output than you want. You can easily add more conditions on file/class/function names to avoid printing unwanted stuff.
Perftools might give you what you're looking for. It analyzes the entire process and can give you a graphical view that looks something like this. Rack perftools profiler is a rubygem that uses perftools and makes it easy to integrate with a Rails application, so I would recommend going with that if you want to try it.
Firstly stacktrace IS every method call that was on the stack at the time an error occurred, what other history could you want besides this?
Secondly, to answer your question, no there is no easy way to log all method calls. You could up your log level all the way to debug which should give you more stuff in the logs, but this will only be things that someone has actually chosen to log, unrelated to method calls.
It probably wouldn't be that difficult to patch ruby in such a way that every method call will print some log statements before and after the method execution, but this will once again be similar to what a stack trace would give you anyway and potentially less since you won't get line numbers etc.
If you want more info than the stack trace, logging is the way most people would do it.

How to determine the value of a controller variable during execution in Ruby on Rails?

What is the best way for me to determine a controller variable's value during execution?
For example, is there a way I can insert a break in the code, and cause the value of the variable to be output to the screen (or the log)?
Yes. The easiest way is to raise the value as a string. Like so: raise #foo.to_s
Or, you can install the debugger (gem install ruby-debug), and then start the development server with the --debugger flag. Then, in your code, call the debugger instruction.
Inside the debugger prompt, you have many commands, including p to print the value of a variable.
Update: here's a bit more about ruby-debug.
If you have a controller instance variable named #foo, then in your controller you can simply do something like:
logger.debug "#foo is: #{#foo}"
Additionally, you can output the value in your view template using:
<%= debug #foo %>
I prefer using the inspect method like so:
raise #foo.inspect
It has more information than to_s, like the attribute values.
Summary from Jordi Bunster, John Topley, and Jaryl:
I. Quick and dirty way:
raise #foo.inspect
in your controller. Or
<% raise #foo.inspect %>
in your view.
II. Proper logging to you development.log:
logger.debug "#foo == #{#foo.inspect}"
III. Full-fledged debugging:
Install the debugger (gem install ruby-debug), and then start the development server with the --debugger flag. Then, in your code, call the debugger instruction.
Inside the debugger prompt, you have many commands, including p to print the value of a variable.
Raising an exception is the fastest way if you just need to look at a value, but it's worth the time to learn how to use the debugger properly. It's rare that you would only need to just see the value of a variable, you are likely trying to find a bug in your code, and that's what a debugger is for.
Sending the info to the development log is slower than either of the other two options here so far if you learn how to use the debugger (who wants to read through log files). Use the logger for production, you are going to want to see what the value was when somebody calls you up and says everything is broken.
Well, I usually prefer the standard error output
$stderr.print("whatever")
Its simple and does the job.
Add pry-moves to Gemfile: gem 'pry-moves'
Insert binding.pry where you want to stop
Type variable's name to see its value
Then continue by typing c, move to next line with n or perform other debugging actions until you will resolve the issue.

Resources