Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get exceptions to render a plain text version of the Rails development error page?

I am using rails-api to build an API with no web interface. When I get errors in development, I'd love to see just the error message and stacktrace in plain text without all of the HTML wrapping. How do I override the global exception handling so it renders the stacktrace in development mode in plain text/JSON, and a generic error message in production?

like image 331
Sam Grossberg Avatar asked Aug 22 '13 00:08

Sam Grossberg


People also ask

How do you handle exceptions in Rails?

Exception handling in Ruby on Rails is similar to exception handling in Ruby. Which means, we enclose the code that could raise an exception in a begin/end block and use rescue clauses to tell Ruby the types of exceptions we want to handle.

How do I return a 404 rail?

To return a 404 header, just use the :status option for the render method. If you want to render the standard 404 page you can extract the feature in a method. If you want the action to render the error page and stop, simply use a return statement.

What are Ruby exceptions?

An exception is an unwanted or unexpected event, which occurs during the execution of a program, i.e. at runtime, that disrupts the normal flow of the program's instructions. In Ruby, descendants of an Exception class are used to interface between raise methods and rescue statements in the begin or end blocks.


2 Answers

I would suggest that including the stack trace in production code is probably not a good idea from a security stand point.

Here is how I would do it:

render :json => {message:exception.message, stack_trace: exception.stacktrace}

I hope this helps.

After Sam's clarification I can add:

In your base controller for your API (probably ApplicationController):

class ApplicationController < ActionController::Base
    ...
    rescue_from Exception do |exception|
        error = {message:exception.message}
        error[:stack_trace] = exception.stacktrace if Rails.env.development?
        render :json => error
    end
    ...
end

Caveat: You may not want to rescue from every single exception in this way but this is how you'd do it if you did.

like image 141
donleyp Avatar answered Nov 10 '22 10:11

donleyp


Some improvements over @donleyp answer to get a clean trace in Rails 3.2 and output generic error info in production:

class ApplicationController < ActionController::API   
    ...   
    rescue_from Exception do |exception|
        if Rails.env.development?
            error = {message:exception.message}
            error[:application_trace] = Rails.backtrace_cleaner.clean(exception.backtrace) 
            error[:full_trace] = exception.backtrace 
            render :json => error
        else
            render :text => "Internal server error.", :status => 500
        end   
    end
    ...    
end
like image 2
Christopher Oezbek Avatar answered Nov 10 '22 11:11

Christopher Oezbek