How can I print debug string in Rails? - ruby-on-rails-3

Are there simple ways to print debug strings in Rails? Something like the OutputDebugString() function in Windows.

http://guides.rubyonrails.org/debugging_rails_applications.html
"To write in the current log use the logger.(debug|info|warn|error|fatal) method from within a controller, model or mailer:"
logger.debug "Person attributes hash: #{#person.attributes.inspect}"
logger.info "Processing the request..."
logger.fatal "Terminating application, raised unrecoverable error!!!"
You could also use raise object.inspect.
Or, if you want more powerful debugging tool, take a look at pry: http://railscasts.com/episodes/280-pry-with-rails
binding.pry in your code and you'll be able to debug ALL THE THINGS!

Related

Spock & Spock Reports: how "catch" and customize the error message for AssertionError?

I am working with:
Spock Core
Spock Reports
Spock Spring
Spring MVC Testing
and I have the following code:
#FailsWith(java.lang.AssertionError.class)
def "findAll() Not Expected"(){
given:
url = PersonaUrlHelper.FINDALL;
when:
resultActions = mockMvc.perform(get(url)).andDo(print())
then:
resultActions.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_XML))
}
Here the code fails (how is expected) because the method being tested really returns (MediaType.APPLICATION_JSON) instead of (MediaType.APPLICATION_XML).
So that the reason of #FailsWith(java.lang.AssertionError.class).
Even if I use #FailsWith(value=java.lang.AssertionError.class, reason="JSON returned ...") I am not able to see the reason through Spock Reports
Question One: how I can see the reason on Spock Reports?.
I know Spock offers the thrown() method, therefore I am able to do:
then:
def e = thrown(IllegalArgumentException)
e.message == "Some expected error message"
println e.message
Sadly thrown does not work for AssertionError.
If I use thrown(AssertionError) the test method does not pass, unique way is through #FailsWith but I am not able to get the error message from AssertionError
Question Two how is possible get the Error Message from AssertionError?
I know I am able to do something like
then: "Something to show on Spock Reports"
But just curious if the question two can be resolved..
regarding Question one:
if you look at FailsWithExtension#visitFeatureAnnotation you can see that only value from the #FailsWith is evaluated, reason is not touched at all. What you could do is introduce you own type of annotation (custom one, e.g. same as #FailsWith) and override AbstractAnnotationDrivenExtension#visitFeatureAnnotation. There you have access to reason parameter.
regarding Question two:
please look at this link: http://spock-framework.3207229.n2.nabble.com/Validate-exception-message-with-FailsWith-td7573288.html
additionally maybe you could override AbstractAnnotationDrivenExtension#visitSpec and add custom listener (overriding AbstractRunListener). Then you have access to AbstractRunListener#error method whose documentation says:
Called for every error that occurs during a spec run. May be called multiple times for the same method, for example if both
* the expect-block and the cleanup-block of a feature method fail.
Didn't test for Question two, but it may work. I've used sth similar.
Enjoy,
Tommy

Rails 3: How to report error message from the controller's "create" action?

In my "create" action on a form, I successfully save (1) MyObject to my local database and (2) OtherObject to a third-party database via its Ruby API. When something goes wrong with the save to the third party, I get an error in the form of a Ruby exception.
My question is: How do I stop the form submit and report the exception message to the client?
If this is not possible, what would be the best alternative?
Depending on whether you want to rollback your local database call, you might want to consider using Transactions. Something along these lines:
def create
ActiveRecord::Base.transaction do
#myobject = MyObject.create!(params[:myobject])
begin
# call third-party
rescue Exception => e
flash[:exception] = e.message
raise ActiveRecord::Rollback # Raise this to cause a rollback on MyObject
end
end
# redirect_to or render... might have to pick depending on if you got an exception
end
This will store the exception message into the flash which you can use to display to the user. Note Do not store the entire Exception object into the flash, you will definitely see overflow errors if your exception objects are too big.
If you're not too concerned about rolling back the MyObject creation, then you can just use a simple begin...rescue similar to what I showed in my example. You may need to determine whether you want to do a redirect_to or render depending on whether an exception occurred, but you can always conditionally determine that based on whether flash[:exception].nil? is true or not.

Rails3: Make update/create fail from model?

There's got to be an easy way to do this, but I cannot find an answer...
When some creates or updates a WorkRequest in my app, I do other processing, including creating a Workflow object. I do some checking to make sure, for example, there isn't more than one Workflow already created for this WorkRequest. If there is, I want the update/create to fail with an error message. I just can't see how to do this. I tried returing false from my before_update callback method, but this did not work.
Do I raise an error and rescue it in my controller? What is the right way to do this in Rails 3?
Any help would be much appreciated.
This is why you have validations. You can implement an own validation like this:
class ...
validate :my_validation
def my_validation
if workflows > 1
errors.add(:workflow, "cannot be more than one" )
end
end
end

What is the difference when using flash :error, :alert, and :notice?

As the title of the question asks, I am interested in knowing if there is any difference when using flash[:error], flash[:alert], and flash[:notice]. If so, when is it appropriate to use each, and why?
flash is a Rails mechanism to persist some information across 2 requests. You set something in flash hash in one request and it's available in the very next request you receive from that same client.
Since flash is just a "hash" you can use it like one. Which means you can provide your preferred key (:alert/:error/:notice) and put whatever message string you wish as the value.
The semantics of what or when to use :alert/:error/:notice are really up to you to manage. Having said that, the general best practice is to use :notice when things are OKAY and is displayed in a greenish hue, and use :error when things are NOT OKAY and is displayed in a reddish hue. It is completely okay if you want to use :alert for another type of message on your web app. I've used it before for informational purposes in a yellowish hue.
:alert and :notice functionally differ from other keys you invent. FlashHash provides convenience accessors for the two: flash.alert , flash.notice. Rails' preference for these two further rears its way into redirect_to which will only accept :alert, :notice, or :flash.
However, a commit in July 2012 to edge Rails allows the privilege of adding other flash types. Here's an example of adding custom flash types in Rails 4:
# app/controllers/application_controller.rb
class ApplicationController; add_flash_types(:error, :annoyance); end
# app/controllers/monopoly_controller.rb
class MonopolyController < ApplicationController
def chance
...
redirect_to haha_path, annoyance: "Go directly to jail. Do not pass Go. Do not collect $200."
end
end
# app/views/haha/index.html.erb
<%= annoyance %>
this is just a classification. it generates the div #error.error or div#notice.notice you connect the logic you want above
litte sample :
.alert, .error, .notice, .success { padding:.8em 0; margin:0 0 2px 0; border:2px solid #ddd; font-size:1.6em; text-align:center;}
.error { background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4; }
.notice { background:#FFF6BF;color:#514721;border-color:#FFD324; }
.success { background:#DDFCD5;color:#000;border-color:#44A815; }
.alert { background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4; }
.error a {color:#8a1f11;}
.notice a {color:#514721;}
.success a {color:#264409;}
.alert a {color:#8a1f11;}
They are just different classifications. I mainly use :error and :notice. Notice I use for informational messages ("your password has been changed", "changes saved", etc). I reserve :error for critical things/problems ("Your passwords do not match", "Login failed", etc)
I also use a :message class too pass along the StandardError message trapped in my exception handlers. Using 2 or 3 classes allows you to display up to that many messages in response to a single event or result, each conveying a different aspect of the outcome, e.g. informational, an error based on what the application knows and an error based on what the system knows.

getting result from a function running "deferToThread"

I have recently started working on twisted not much familiar with its functions.I have a problem related to "deferToThread" method...my code is here to use this method
from twisted.internet.threads import deferToThread
from twisted.internet import reactor
results=[]
class Tool(object):
def exectool(self,tool):
# print "Test Class Exec tool running..........."
exec tool
return
def getResult(self,tool):
return results.append(deferToThread(self.exectool, tool))
to=Tool()
to.getResult(tools)
f=open(temp).read()
obj_tool=compile(f, 'a_filename', 'exec')
[ at 0x8ce7020, file "a_filename", line 1>, at 0x8cd4e30, file "a_filename", line 2>]
I am passing tools one by one in getResults() method it executs successfully & prints the results what script written in the file objects.
I have to store the result of tools executing in some variable so that I can save it in database.How to achieve this cause when i call re=to.getResult(tools) and print "re" it prints none.
I HAVE TO STORE ITS RESULTS IN DATABASE? IS THERE SOMETHING I CAN DO?
thanx in advance
There are two problems here.
First, deferToThread will not work if you never start the reactor. Hopefully this code snippet was actually extracted from a larger Twisted-using application where the reactor is running, so that won't be an actual problem for you. But you shouldn't expect this snippet to work unless you add a reactor.run() call to it.
Second, deferToThread returns a Deferred. The Deferred fires with the result of the callable you passed in. This is covered in the API documentation. Many APIs in Twisted return a Deferred, so you might want to read the documentation covering them. Once you understand how they work and how to use them, lots of things should be quite a bit easier.