Rescuing error does nothing? - ruby

I'm trying to rescue an exception with this method:
def template_deleted
mailchimp_client.templates.info(mailchimp_id)
rescue Mailchimp::InvalidTemplateError => error
puts "Template deleted in Mailchimp: #{error}"
return true
else
return false
end
And no matter what I use to output the message, whether it's STDERR, STDOUT, log.error, p, puts, or print, nothing gets out to the environment's log. This should definitely be returning an error, because the template definitely doesn't exist in Mailchimp.
When I try the same code in the console I can read the error just fine, so either there's something wrong with the rescuing itself (i.e., my method is returning false which it shouldn't), or there's something wrong with the way I'm outputting it.

To output something in the log file of the current environment, use the Rails logger like this:
logger.debug "Template deleted in Mailchimp: #{error}"
You can replace the debug method call with any logging level name, that are briefly described in the link above. Also don't forget to make sure you're running in correct environment!

Related

RSpec: Expecting a method to be called causes that method to not actually be called

I have some code that could be represented in very simple terms as:
def method_a(key)
hash = method b(key)
hash.delete(key)
end
def method_b(key)
return { key => 1 }
end
and then an rspec test like
it 'calls method_b'
expect(someClass).to receive(:method_b).with(key)
method_a(key)
end
However I then get an error in the second line of method_a because it's trying to call delete on a nil object. When I debug, I can see that the logic inside method_b is never actually being invoked. It's not failing somewhere in method_b, it's literally not calling it at all. If I get rid of the expect statement in the test, this error goes away. It seems like the expect statement is causing it to just skip over the actual call to method_b, leaving me with a nil value instead of the hash I'm expecting.
Is there a way I can stop it from skipping over method_b, or at least terminate execution once the expect statement is successful, so I don't run into the error on the next line?
When you set a message expectation, it overrides the original code, unless you explicitly tell RSpec not to:
expect(someClass).to receive(:method_b).with(key).and_call_original

How to Write mock of method using with to send params

Hi I want to know how can I write rspec for the following
def find_user(content)
user = User.find(content.to_i) ||
User.find(email: content) rescue
nil
end
I tried writing
It "user with user name" do
expect(User).to receive(:find).with(email: "test#a.com").and_return(user)
End
But I am gettig error saying
Argument Error
Block not Passed
Can someone please tell what am i missing
I may look first at your code here.
def find_user(content)
user = User.find(content.to_i) ||
User.find(email: content) rescue
nil
end
What is content? I looks like you're expecting either a user_id or an email address.
Doing this from the console:
irb(main):080:0> User.find("email#email.com".to_i)
=> ActiveRecord::RecordNotFound (Couldn't find User with 'id'=0)
So it seems as if having a generic find_user method may be contributing to some of the test writing confusion.
Many times, overly complex tests point to overly complex code.
Perhaps you need one method
find_user_by_email(email)
and another
find_user_by_id(id)
Also, refer to https://api.rubyonrails.org/v6.1.3.2/classes/ActiveRecord/FinderMethods.html#method-i-find_by
It will automatically return nil if nothing is found.
Start there, And then like the other commenters, then post your class, and the spec and we can go from there.

get the backtrace in a sinatra app

Im trying to get the backtrace in sinatra in case of an error.
I know rails has one in
Rails.respond_to?(:backtrace_cleaner)
and I saw that sinatra is suppose to have one (by default enabled) in STDERR
So i tried
STDERR.inspect
and I got #<IO:<STDERR>>
When rescuing the exception, catch the exception object.
begin
raise "hello"
rescue => e
e.backtrace
end
In Ruby you can call a method caller at any place and get a full backtrace as an array.

AWS S3 NoSuchBucket Exception Not Caught in Rescue Clause

I'm trying to get a bucket in Ruby using the AWS SDK, and trying to catch a NoSuchBucket error. Problem is, my rescue block is not catching the error, and so my app crashes. Here is the relevant code:
begin
b = s3.buckets[bucket_name]
rescue AWS::S3::Errors::NoSuchBucket
puts Invalid bucket name.
exit 1
end
and the error message is:
C:/Ruby193/lib/ruby/gems/1.9.1/gems/aws-sdk-1.5.6/lib/aws/core/client.rb:277:in
`return_or_raise': The specified bucket does not exist (AWS::S3::Errors::NoSuchBucket)
Am I just making a stupid beginner syntax error, or is there a bug in the AWS code that's not actually throwing the error? I've also tried catching all errors and still no dice.
b = s3.buckets[bucket_name]
Doesn't actually make any requests and won't ever through exceptions like NoSuchBucket.
It just returns a bucket object that knows what its name is. A request only happens when you actually try to do something with the bucket (list its contents, add a file to it) and it is at this point that NoSuchBucket is raised. This is outside of your begin block and so your rescue doesn't handle it. If you need to rescue that exception, you need to be putting your begin/rescue around the places that you actually use the bucket.
If you are just trying to validate that it actually exists you could do something like
s3.buckets[bucket_name].exists?

Ruby append to string if error contains string

I have a Slack Bot that needs to respond in an error condition. If the error has certain text in it, I want to append some additional information to the return message. This block of code works fine if I comment out the message += line but breaks if I do not. When I try to replicate this in irb everything works fine too.
Does something look obviously wrong here?
begin
scan = #nsc.scan_devices(devices)
rescue Nexpose::APIError => e
puts "[!] API ERROR: Most likely caused by an orphaned asset (#{device_ids})"
puts "[!] #{e}"
$slackbot_logger.error("[!] API ERROR: Most likely caused by an orphaned asset (#{device_ids})")
$slackbot_logger.error(e)
# Message back to Slack
message = "<##{user_id}> scan for #{ip_list} *failed* :sob:"
message += 'There is a scheduled blackout Tues/Thurs until 1000 CST' if e.include? 'blackout'
SlackFunctions.slack_send_message(message, channel)
return
end
This particular error object (and maybe all error objects) did not have an include? method. Therefore using e.to_s seems to do the trick.

Resources