Главная » Error » Untangling the Rails Asset Pipeline, Part 4

Untangling the Rails Asset Pipeline, Part 4

Table of Contents

  1. Help! My production site is completely unstyled
  2. I’ve precompiled, but styles still don’t load
  3. My main stylesheet works, but others do not
  4. When precompiling, I get errors
  5. I’m trying to compile on-the-fly instead
  6. Pages load slowly
  7. When in doubt…

Help! My production site is completely unstyled

In this scenario you deploy to production, load your site and find that the HTML source code is fine, but no CSS is loading at all. Pull up the Webkit console (⌥⌘C in Safari, ⌥⌘J in Chrome) and you see red 404 error messages for each CSS and JavaScript file. Yikes!

I made this mistake myself when first experimenting with Rails 3.1. The solution is easy: run this very important command on the production server:

bundle exec rake assets:precompile

This is needed because Rails by default does not generate or serve its CSS assets in production, so you need to compile them beforehand. For further explanation on this topic, read Part 2: Production of this series.

Exception != Error

Before we get to rescuing errors there something important we need to understand. As seen in the above example we get an ActiveRecord::RecordNotFound error. The try catch block in ruby would look something like this which works just fine.

rescue from RecordNotFound error

But when you want to rescue from all Exceptions then it is really important to know the difference between Exception and Error in Ruby. Never rescue from Exception.It tries to handle every single exception that inherits from the Exception class and ultimately stops the execution.

rescue from Exception

Instead we need to rescue from StandardError. Here is an excellent blog post which explains the difference http://blog.honeybadger.io/ruby-exception-vs-standarderror-whats-the-difference/.

rescue from StandardError

The Rescue

In order to handle the errors we can use the rescue block. The rescue block is similar to the try..catch block if you are from the Java world. Here is the same example with a rescue block.

begin..rescue

With this approach the errors are rescued in the controller methods. Though this works perfectly it might not be best approach to handle errors. Here are a few reasons to consider an alternate approach.

  1. Fat Controllers: Do read this excellent article by Thoughtbots https://robots.thoughtbot.com/skinny-controllers-skinny-models.
  2. The DRY principle: We are simply repeating the error block in various places that goes against the DRY(Don’t Repeat Yourself) principle.
  3. Maintainability: Harder to maintain code. Changes to the error such as the format would involve major changes.

An alternate approach would be to move the error handling block to the ApplicationController. A much cleaner approach is to write an Error handler module.

More from Rails, Ember & Beyond

A collection of Articles on Ruby, Rails & much more.

Rails, Ember & BeyondRead more from

About Help Terms Privacy

class=”dr ds ry rz” aria-hidden=”true”>

Final Notes

The Modular approach is the Rails way of handling errors. Whenever we want to change a particular error message/format we just have to change it in one place. By this approach we also separate the Application logic from error handling thus making the ControllersSlickinstead of Fat.

It’s best practice in Rails to have Skinny Controllers & Models.

Here is the complete Source code for handling errors with modular approach. Please do hit the Recommend button if you found it useful. And as always feel free to respond if you have any doubts. Cheers!

12

I’ve precompiled, but styles still don’t load

If you’ve precompiled, double-check that compilation actually worked by listing the contents of the public/assets directory of your application on the production server:

ls -l public/assets

You should see compiled and cache-busted versions of all your CSS, JS and image assets. If not, review the output of rake assets:precompile for errors.

Assuming precompilation worked, make sure that you are accessing your application by way of the web server (i.e. Nginx or Apache, usually on port 80). If you haven’t configured the web server yet and are hitting your application directly (i.e. via thin or webrick on port 3000), assets will not work.

If you don’t wish to set up a web server 1 , or you want to test your Rails application in production before doing so, set the following in production.rb:

config.serve_static_files=true

Check out Part 3: Configuration of this series to go more in-depth on this topic.

Error Handling — Modular Approach

In order to handle the errors in one place our first option would be to write in under ApplicationController. But it’s best practice to have it separated from the Application logic.

Let us create a module which handles errors on a global level. Create a module ErrorHandler(error_handler.rb) and place it under lib/error (or anywhere to load from) and then include it in our ApplicationController.

Important: Load the Error module on App startup by specifying it in config/application.rb .

Include lib/error/error_handler.rb Module in application_controller.rb

Note: I am using a few Helper classes to render the json output. You can check it out here.

Before proceeding with the error_handler module here is a really interesting article on modules that you should definitely check out. If you notice the self.included method in a module works the same as if it is placed in the original class. So all we have to do is include the ErrorHandler module in ApplicationController.

users_controller.rb

Let’s refactor the ErrorModule to accommodate multiple error handling blocks. It looks much cleaner this way.

Refactored lib/error/error_handler.rb

If you notice ActiveRecord:RecordNotFound error also inherits StandardError. Since we have a rescue mechanism for it we get a :record_not_found. The StandardError block acts as a Fallback mechanism that handles all errors.

How to transfer files between servers using Netcat


Amr Saeed

Amr Saeed

Google Forms + Jira Integration


Satyam Pushkar

Satyam Pushkar

第三方 API 整理

Jorge Quitério

Jorge Quitério

in

iostrap

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ali Sepehri.kh

SOLID Principles: Liskov Substitution Principle


Lyla

Lyla

in

Allset App

Open Letter: Recent Changes

About Help Terms Privacy

class=”dr ds ti tj” aria-hidden=”true”>

Introduction to Matplotlib


彼得潘的 iOS App Neverland

彼得潘的 iOS App Neverland

in

彼得潘的 Swift iOS App 開發問題解答集

Discover the latest updates to Allset


STEPN Official

STEPN Official

Define your own Exception.

We can also define our own Error classes that inherits from StandardError. To keep things simple we can create a CustomError class that holds the common variables and methods for all the user defined error classes. Now our UserDefinedError extends the CustomError.

lib/error/custom_error.rb and lib/error/not_visible_error.rb

We can override the methods specific to each Error. For example NotVisibleError extends CustomError. As you may notice we override the error_message.

NotVisibleError handled in ErrorModule

To handle all user defined Errors all we have to do is rescue from CustomError. We can also rescue from the specific Error if we want to handle it differently.

Recommended from Medium

Alec Sutherland

Alec Sutherland

My main stylesheet works, but others do not

By default, Rails only precompiles application.css. If you have additional stylesheets, like perhaps ie.css or print.css, these won’t be precompiled unless you explicitly tell Rails to do so.

config.assets.precompile+=[‘ie.css’,’print.css’]

Refer to part 3 of this series for more information on the config.assets.precompile setting.

When precompiling, I get errors

To precompile all of your CSS and JavaScript, Rails needs to have loaded all the required gems. That means that if your stylesheets use Compass, the compass-rails and sass-rails gems have to be present. Likewise CoffeeScript files need coffee-rails.

Make sure all asset pipeline gems are declared at the root level of your the Gemfile. For example:

gem”coffee-rails”,”~> 4.1.0″gem”sass-rails”,”~> 5.0″gem”uglifier”,”>= 1.3.0″

Murphy’s Law:

As Murphy’s Law states anything that can go wrong will go wrong, which is why it is important to be prepared for it. It applies everywhere, even in Software Development. The application that we develop must be robust enough to handle it. In other words it must be Resilient. This is exactly what this blog post is about.

Anything that can go wrong, will go wrong.

— Murphy’s Law

In Rails a typical workflow we handle errors in the Controller level. Let say you are writing an API using Rails. Consider the following controller method to render user JSON.

users_controller.rb

When the user object is found it renders it as json, otherwise renders the error json. This is the typical way of writing a show method is Rails. But here is the catch. When user record is not found it doesn’t go into the else block it renders the fallback 500.html content. Well that was unexpected. This is because if record is not found it raises a RecordNotFound error. The same happens with find_by! or any finder methods with a bang.

ActiveRecord::RecordNotFound

gRPC with .NET : Server, Client & Bidirectional Streaming


Sam Richard

Sam Richard

in

featurepreneur

I’m trying to compile on-the-fly instead

When testing your deployment process, you may find yourself wanting to skip rake assets:precompile and compile assets on-the-fly instead, the way Rails normally works in development mode. After all, the precompilation step can take quite a long time for a large app.

In Rails 3.1 or 3.2, if you simply set config.assets.compile=true, the pages of your app might fail to load with obscure errors relating to Sass, Compass or CoffeeScript. That’s because in production, these versions of Rails did not normally load the gems required for compiling assets. Tell Rails you want to load them by uncommenting this line in application.rb:

Bundler.require(:default,:assets,Rails.env)

For a more detailed walkthrough of this setup, refer to the config.assets.compile section of Part 3: Configuration.

Pages load slowly

Large stylesheets and JavaScript files take time to download and parse, especially on slower devices like the original iPad. If your application is not delivering the proper cache хедерs, the browser may re-fetch your stylesheets for each and every page, resulting in noticeable sluggishness.

Also remember that in production, Rails is not serving your assets: that’s the web server’s job. Solving this problem therefore involves configuring the web server to serve assets with far-future expires хедерs. For example, in Nginx:

location ~ “/assets/.*-[0-9a-f]{32}.*” {
gzip_static on;
expires max;
add_хедер Cache-Control public;
break;
}

See the Rails asset pipeline guide for more details.

404 and 500

You can handle common exceptions like 404 and 500, although it’s totally up to the developer. We need to create a separate controller class, ErrorsController for it.

errors_controller.rb

Tell Rails to use Routes to resolve exceptions. We just have to add the following line to application.rb.

config.exceptions_app = routesconfig/routes.rb

Now 404 exceptions fallback to errors#not_found and 500 to errors#internal_server_error.

Источники

  • https://mattbrictson.com/untangling-the-rails-asset-pipeline-part-4-troubleshooting
  • https://medium.com/rails-ember-beyond/error-handling-in-rails-the-modular-way-9afcddd2fe1b
  • https://itnext.io/how-to-speed-up-assets-precompile-for-ruby-on-rails-apps-e0338d8d7301
[свернуть]
Решите Вашу проблему!


×
Adblock
detector