I am performing a GET request in Ruby and not sure why I am sometimes getting the following stack trace.
RestClient::MethodNotAllowed: 405 Method Not Allowed
[GEM_ROOT]/gems/rest-client-1.6.8/lib/restclient/abstract_response.rb:48:in return!
[GEM_ROOT]/gems/rest-client-1.6.8/lib/restclient/request.rb:269:in process_result
[GEM_ROOT]/gems/rest-client-1.6.8/lib/restclient/request.rb:212:in block in transmit
/usr/lib/ruby/2.0.0/net/http.rb:852:in start
[GEM_ROOT]/gems/rest-client-1.6.8/lib/restclient/request.rb:206:in transmit
[GEM_ROOT]/gems/rest-client-1.6.8/lib/restclient/request.rb:68:in execute
[GEM_ROOT]/gems/rest-client-1.6.8/lib/restclient/request.rb:35:in execute
[GEM_ROOT]/gems/rest-client-1.6.8/lib/restclient.rb:70:in get
It's especially confusing because the stack trace does not say which method is not allowed. What might be the cause of this error?
You could try to rescue the exception. This way you can access the http_body of the response. If you're lucky, this might give you an insight on what went wrong.
begin
RestClient.get 'http://example.com/resource', {:params => {:id => 50, 'foo' => 'bar'}}
rescue RestClient::Exception => e
puts e.http_body
end
Related
We are getting an error when running a query job on BigQuery :
'message' => 'Request timed out. Please try again.',
'reason' => 'timeout',
'location' => 'script'
We will be running it again as it requested, but since it takes 1/2 hour for it to time out, it would be helpful if we knew what the problem is so we can avoid it.
Specifically:
What does "script" mean in this context? Is it the SQL-query or one
of the UDFs? (the query calls 3 UDFs).
The exact same query failed twice already with "internal error". The "request timed out" was its 3rd attempt at mocking us. Any correlation between the two error types?
It would be really helpful to receive more detailed information on what failed to work, so that we can track it down.
Iam using delayed job in a rails application. I want to notify an error to airbake whenever a delayed job fails. I checked on github and leant about the failure method.
I want to send the last_error attribute of failed delayed job to airbrake. Something like this:
class ParanoidNewsletterJob < NewsletterJob
def perform
end
def failure
Airbrake.notify(:message => self.last_error, :error_class => self.handler)
end
end
But it gives me the following runtime error:
undefined method `last_error' for #<struct ParanoidNewsletterJob>
Please help me figure out how I can notify Airbrake the last_error of a failed delayed_job.
Many Thanks!!
You should be able to pass the job to the failure method, and then extract the last_error from the job. i.e.
def failure(job)
Airbrake.notify(:message => job.last_error, :error_class => job.handler)
end
this should work fine
def failure(job)
Airbrake.notify(:message => job.error, :error_class => job.error.class, :backtrace => job.error.backtrace)
end
There are two ways you can achieve what you want:
A job specific method which only applies to the type of job you want by implementing the failure method with the job as the parameter. The job will contain error and last_error. And this is what other answers are about.
A global option where a plugin can be developed to apply it to any job type created. This is desired if all jobs need to be monitored. The plugin can be registered and perform actions around various events in the lifecycle of a job. For example, below is a plugin to update the last_error if we want to process it before storing to database
One example below:
require 'delayed_job'
class ErrorDelayedJobPlugin < Delayed::Plugin
def self.update_last_error(event, job)
begin
unless job.last_error.nil?
job.last_error = job.last_error.gsub("\u0000", '') # Replace null byte
job.last_error = job.last_error.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
end
rescue => e
end
end
callbacks do |lifecycle|
lifecycle.around(:failure) do |worker, job, *args, &block|
update_last_error(:around_failure, job)
block.call(worker, job)
end
end
end
Basically it will be called when any failure occurs for any job. For details on how this callback thing work, you can refer to A plugin to update last_error in Delayed Job.
I have an iteration in which I am calling set_table_name for some model. The idea is that in each iteration, the model changes its table. Sometimes, the table won't exist, in that case, an error of this kind will happen:
Mysql2::Error: Table 'db_name.table_name_xyz' doesn't exist
I want the iteration to keep running and not abort because of the error. I've wrapped the set_table_name line of code with a begin and rescue, but no exception seems to be raised as the script instantly aborts on error (it doesn't execute the rescue code). Here's the code:
((start_year)..(start_actual_year)).each do |year|
begin
Data.set_table_name("Secciones#{year}#{year + 1}")
rescue Exception => e
next
end
end
Can I rescue this kind of error? What should I do? Thanks!
Are you sure you are catching the exception correctly? Here's more info if needed.
begin
# Your code here.
rescue Exception => e
# Output the exception that it is catching.
puts e.message
ensure
# The ensure block is used to close a db connection if needed.
end
I have an rspec test that I expect to fail, but it is passing because the code that it is testing rescues the exception that rspec raises. Here's an example of the situation:
class Thing do
def self.method_being_tested( object )
# ... do some stuff
begin
object.save!
rescue Exception => e
# Swallow the exception and log it
end
end
end
In the rspec file:
describe "method_being_tested" do
it "should not call 'save!' on the object passed in" do
# ... set up the test conditions
mock_object.should_not_receive( :save! )
Thing.method_being_tested( mock_object )
end
end
I knew that the execution was reaching the "object.save!" line of the method being tested, and the test should therefore be failing, but the test passes. Using the debugger in the rescue block, I find the following:
(rdb:1) p e # print the exception object "e"
#<RSpec::Mocks::MockExpectationError: (Mock "TestObject_1001").save!
expected: 0 times
received: 1 time>
So basically the test is failing but, but the failure is being suppressed by the very code it is trying to test. I cannot figure out a viable way to stop this code from swallowing Rspec exceptions without somehow compromising the code. I don't want the code to explicitly check if the exception is an Rspec exception, because that is bad design (tests should be written for code, code should never be written for tests). But I also can't check that the exception is any particular type that I DO want it to catch, because I want it to catch ANYTHING that could be raised in a normal production environment.
Someone must have had this problem before me! Please help me find a solution.
Assuming the code is correct as-is:
describe "method_being_tested" do
it "should not call 'save!' on the object passed in" do
# ... set up the test conditions
calls = 0
mock_object.stub(:save!) { calls += 1 }
expect {Thing.method_being_tested(mock_object)}.to_not change{calls}
end
end
If there's no need to catch absolutely all exceptions including SystemExit, NoMemoryError, SignalException etc (input from #vito-botta):
begin
object.save!
rescue StandardError => e
# Swallow "normal" exceptions and log it
end
StandardError is the default exception level caught by rescue.
from rspec-mock:
module RSpec
module Mocks
class MockExpectationError < Exception
end
class AmbiguousReturnError < StandardError
end
end
end
Do you really need to catch Exception? Could you catch StandardError instead?
Catching all exceptions is generally a bad thing.
I would refactor it like so:
class Thing do
def self.method_being_tested!( object )
# ... do some stuff
return object.save
end
end
If you want to ignore the exception thrown by save! there is no point in calling save! in the first place. You just call save and inform the calling code accordingly.
According to save bang your head, active record will drive you mad, we should avoid using save! and rescue idiom for exceptional situations. Given that, say a model needs to #post.mark_rejected.
If the code in mark_rejected fails due to one of the below problems, should an exception be thrown? :
if there is a validation problem
if a non-nullable-field was being assigned a null
if there was a connection loss to database
If we do not throw an exception, then:
controller action would have to check for return value of mark_rejected and do it's thing
we are not expecting an exception from that method call, so we do not write a rescue clause in the controller action, thus the exception bubbles up to (..wherever..) and will probably show up as some (500 HTTP?) error
Example code:
def mark_rejected
...
save!
end
or
def mark_rejected
...
save
end
save! will raise an error if not successful.
save will return boolean value like true or false.
There's more overhead in an exception, so there is a performance issue, especially when it can be expected that it will likely be thrown often, as is the case with save.
It is fewer lines of code to check if the return value is false than rescue an exception, so I don't see how it's a problem having to check for the return value if you already have to rescue the exception. How often would an exception thrown by save! ever have to bubble-up the call stack in practice? Rarely, if ever, in my experience.
If there is an exception thrown when calling save as opposed to save! you should want it to show a 500 error page because that's what happened: an unrecoverable, unknown, unexpected internal server error.
Suggestion: use save when it's on the last line; save! otherwise.
The idea: if the method is returning the save's result you should not throw exception and let the caller to handle save problems, but if the save is buried inside model method logic you would want to abort the process with an exception in case of failure.