Let's say you have the following example code block:
def next_page(next_token)
client.list_order_items_by_next_token(next_token)
rescue => error
binding.pry
end
Without diving into the issue that this rescue is capturing all errors and how that is bad (this block has been modified) is there a way to determine the method list_order_items_by_next_token caused the issue? I know the stack trace is available but that does not feel right.
Just use
error.backtrace
Don't worry about performance.
By the time you rescue the exception the cost of creating the backtrace has already occurred. The backtrace is created when the exception is raised. And it is expensive! Ruby has to create O(N) new strings whenever an exception is raised, where N is the depth of the stacktrace. Which can be 1000+ in a common Rails application. It gets even worse in a loop. And all these strings are usually never used and just clog up garbage collection. In our production system those backtrace strings are one of the major causes of performance degradation. But as I said, that cost occurs when the exception is raised, accessing the backtrace later is free of cost.
Related
I am logging the errors of a rails application using exception_logger (https://github.com/ryancheung/exception_logger) and it is working file. But it is logging the backtrace which I don't want to be logged.
Is there any way to stop logging backtrace?
Side note: why would you want that? Backtraces are very valuable as they tell you exactly where a problem (exception) occurs in your code.
Anyway, it seems that logging exceptions backtrace is not configurable in the exception_logger gem. So your only option would be to monkey-patch some of its code. I'd try to patch the setter for the backtrace in the LoggedException model.
Put this into an initializer under lib/initializers:
# lib/initializers/logged_exception_patch.rb
module ExceptionLogger
class LoggedException < ActiveRecord::Base
def backtrace=(trace)
write_attribute :backtrace, ""
end
end
end
This code will make the model just ignore back traces when saving the logged exceptions and save a blank string to the backtrace column instead.
But let me say again - I think that if you are logging real exceptions on a real site, sooner or later you will regret not logging the back traces because you will get an exception with an unclear origin...
I have created a method that is called for each web element accessed by the scripts, as to avoid the "StaleElementReferenceError" thrown by selenium. This is how the code looks:
def reach_element(page,element)
begin
element.wait_until_present
rescue Selenium::WebDriver::Error::StaleElementReferenceError
puts '* retrying to reach element'
page.refresh
retry
end
end
It appears that the StaleElementReferenceError is ignored and the tests keep failing with this error.
Am I doing something wrong?
CORRECTIONS:
This error shouldn't appear at all for it to be rescued by ruby.
The main cause was the old version of watir-webdriver gem. If you still encounter this error, a simple gem update should do the trick.
We mostly got rid of stale element issues for when you take an action on an element in watir-webdriver last year. This is the code: https://github.com/watir/watir-webdriver/blob/master/lib/watir-webdriver/elements/element.rb#L597
When an action is taken on the element, but it is stale, it will re-look it up with the selector provided. It will fail for not existing if it isn't there.
Are you seeing your element go stale between when you locate it, but before it becomes visible? That's an interesting use case that I have plans to fix. If that is your issue, refreshing the page will force the element to go stale, so that will just repeat your issue. Remove the refresh, and it should keep relocating the stale element until it is present.
If that isn't the issue or that doesn't work, provide a stack trace of what you are seeing.
I am fighting this exception:
ActionView::TemplateError (incompatible character encodings: UTF-8 and ASCII-8BIT) on line #5 of app/views/retain/qs/_qs_row.html.erb:
That is from a template and the excpetion starts with:
app/helpers/retain/qs_helper.rb:111:in `render_row'
app/views/retain/qs/_qs_row.html.erb:5
...
That line of code is:
cache(tag) do
...
end
And at that point I'm confused. According to the stack, we are not inside cache nor are we inside the block that cache yields to -- let we are somehow, somewhere, operating on two strings (probably concatenating them. How do I find out where that operation is happening and the parameters, etc being used?
The frustrating thing also is that I can not recreate this myself. I have to put this into my staging environment and let one of my users in Korea (two of them actually) bump into it.
Anyone have any debugging suggestions? Would it help if I put a rescue in, catch the exception, and print the stack out myself? Would it include more lines?
add to your qs_helper.rb helper file this line
# encoding: utf-8
Related topic
Add "# coding: utf-8" to all files
I added my own rescue and then logged the exception's backtrace. It contained several stack levels below the one that was printed out normally. The exception is coming from within memcache in my case.
I am not sure why the Rails exception handler is not displaying the first 6 or so levels of the stack.
What exactly does this mean -- "Maybe IRB bug!"? What does that tell me about the potential root cause of an exception?
Note that the text "Maybe IRB bug!!" was printed after the stack trace as part of the exception output.
This message means that IRB detected the cause of the stack trace being inside IRB's own code, not in the code you entered to be executed. And depending on what you did before that, it is thus likely that you triggered a bug in IRB.
A stack trace or segfault of a tool itself (as opposed to an error in user-code) is considered a bug almost all of the time. A tool should never die on user data, but always fail gracefully and with meaningful error messages. The one you see here is an attempt for one of those :)
I'm using daemons gem with Rails in addition to daemon_generator plugin. I'm getting this output in the daemons log file:
Logfile created on Sat May 09 20:10:35 -0700 2009 by /
-below you find the most recent exception thrown, this will be likely (but not certainly) the exception that made the application exit abnormally ***
#<NameError: uninitialized constant SmsMessage>
-below you find all exception objects found in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***
#<NoMemoryError: failed to allocate memory>
#<SystemStackError: stack level too deep>
#<fatal: exception reentered>
#<MissingSourceFile: no such file to load -- ./config/global_constants.conf>
#<NameError: uninitialized constant SmsMessage>
I'm finding very hard to make sense from this output. It's displaying different error messages and I can tell it's not it's not the ./config/global_constants.conf issues because I don't call it inside the daemon file. Plus I don't think it's a memory issues as my Mac has 2GB of memory and not many programs running. as for the SmsMessage I'm calling it normally using:
scheduledMessagesParent = SmsMessage.valid.find(:all, :conditions => {:status => $SCHEDULED_MESSAGE})
which works elsewhere in my website!!
I noticed that the logger is called using
ActiveRecord::Base.logger.info "....
Is it possible I have to specify my model's path in another way? I normally call the logger using logger.info without the need for ActiveRecord::Base. If so how to do that?
Any ideas how to go about debugging this problem? is there a way to display stack trace or better error messages?
I resolved this issue by loading the Rails environment with the Daemon. It wasn't included in the tutorial that I got the info from but it works now :)