Skip to content

Commit

Permalink
Merge branch 'master' into hints
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinDaugherty committed Oct 31, 2020
2 parents 081fa84 + 64d5be2 commit d010b26
Show file tree
Hide file tree
Showing 61 changed files with 1,987 additions and 386 deletions.
1 change: 1 addition & 0 deletions .coveralls.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
service_name: travis-ci
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
/doc
/.bundle
/vendor/gems

/gemfiles/*.gemfile.lock
/gemfiles/.bundle
112 changes: 108 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,111 @@
sudo: false
language: ruby
cache: bundler
notifications:
webhooks:
# With COVERALLS_PARALLEL, coverage information sent to coveralls will not be processed until
# this webhook is sent.
# https://coveralls.zendesk.com/hc/en-us/articles/203484329-Parallel-Build-Webhook
- secure: "YnHYbTq51ySistjvOxsuNhyg4GLuUffEJstTYeGYXiBF7HG5h43IVYo8KNuLzwkgsOYBcNo+YMdQX7qCqJffSbhsr1FZRSzBmjFFxcyD4hu+ukM2theZ4mePVAZiePscYvQPRNY4hIb4d3egStJEytkalDhB3sOebF57tIaCssg="
rvm:
- 2.0
- 2.1
- 2.2
- 2.2.10
- 2.3.8
- 2.4.9
- 2.5.7
- 2.6.5
- 2.7.0
- ruby-head
- truffleruby-head
gemfile:
- gemfiles/rails42.gemfile
- gemfiles/rails50.gemfile
- gemfiles/rails51.gemfile
- gemfiles/rails52.gemfile
- gemfiles/rails60.gemfile
- gemfiles/rails42_haml.gemfile
- gemfiles/rails50_haml.gemfile
- gemfiles/rails51_haml.gemfile
- gemfiles/rails52_haml.gemfile
- gemfiles/rails60_haml.gemfile
- gemfiles/rails42_boc.gemfile
- gemfiles/rails50_boc.gemfile
- gemfiles/rails51_boc.gemfile
- gemfiles/rails52_boc.gemfile
- gemfiles/rails60_boc.gemfile
- gemfiles/rack.gemfile
- gemfiles/rack_boc.gemfile
- gemfiles/pry09.gemfile
- gemfiles/pry010.gemfile
- gemfiles/pry011.gemfile
matrix:
fast_finish: true
allow_failures:
- rvm: ruby-head
- gemfile: gemfiles/pry010.gemfile
- gemfile: gemfiles/pry011.gemfile
exclude:
- rvm: 2.2.10
gemfile: gemfiles/rails60.gemfile
- rvm: 2.2.10
gemfile: gemfiles/rails60_boc.gemfile
- rvm: 2.2.10
gemfile: gemfiles/rails60_haml.gemfile
- rvm: 2.3.8
gemfile: gemfiles/rails42.gemfile
- rvm: 2.3.8
gemfile: gemfiles/rails42_boc.gemfile
- rvm: 2.3.8
gemfile: gemfiles/rails42_haml.gemfile
- rvm: 2.3.8
gemfile: gemfiles/rails60.gemfile
- rvm: 2.3.8
gemfile: gemfiles/rails60_boc.gemfile
- rvm: 2.3.8
gemfile: gemfiles/rails60_haml.gemfile
- rvm: 2.4.9
gemfile: gemfiles/rails42.gemfile
- rvm: 2.4.9
gemfile: gemfiles/rails42_boc.gemfile
- rvm: 2.4.9
gemfile: gemfiles/rails42_haml.gemfile
- rvm: 2.4.9
gemfile: gemfiles/rails60.gemfile
- rvm: 2.4.9
gemfile: gemfiles/rails60_boc.gemfile
- rvm: 2.4.9
gemfile: gemfiles/rails60_haml.gemfile
- rvm: 2.5.7
gemfile: gemfiles/rails42.gemfile
- rvm: 2.5.7
gemfile: gemfiles/rails42_boc.gemfile
- rvm: 2.5.7
gemfile: gemfiles/rails42_haml.gemfile
- rvm: 2.6.5
gemfile: gemfiles/rails42.gemfile
- rvm: 2.6.5
gemfile: gemfiles/rails42_boc.gemfile
- rvm: 2.6.5
gemfile: gemfiles/rails42_haml.gemfile
- rvm: 2.7.0
gemfile: gemfiles/rails42.gemfile
- rvm: 2.7.0
gemfile: gemfiles/rails42_boc.gemfile
- rvm: 2.7.0
gemfile: gemfiles/rails42_haml.gemfile
- rvm: ruby-head
gemfile: gemfiles/rails42.gemfile
- rvm: ruby-head
gemfile: gemfiles/rails42_boc.gemfile
- rvm: ruby-head
gemfile: gemfiles/rails42_haml.gemfile
- rvm: truffleruby-head
gemfile: gemfiles/rails42_boc.gemfile
- rvm: truffleruby-head
gemfile: gemfiles/rails50_boc.gemfile
- rvm: truffleruby-head
gemfile: gemfiles/rails51_boc.gemfile
- rvm: truffleruby-head
gemfile: gemfiles/rails52_boc.gemfile
- rvm: truffleruby-head
gemfile: gemfiles/rails60_boc.gemfile
- rvm: truffleruby-head
gemfile: gemfiles/rack_boc.gemfile
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Changelog

See https://github.com/charliesome/better_errors/releases
See https://github.com/BetterErrors/better_errors/releases
9 changes: 2 additions & 7 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,5 @@ source 'https://rubygems.org'

gemspec

gem "rake"
gem "rack"
gem "rspec", "2.14.1"
gem "binding_of_caller", platforms: :ruby
gem "pry", "0.9.12"
gem "yard"
gem "kramdown"
# gem "pry-byebug"
gem 'simplecov', require: false
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2012-2015 Charlie Somerville
Copyright (c) 2012-2016 Charlie Somerville

MIT License

Expand Down
139 changes: 97 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# Better Errors [![Gem Version](https://img.shields.io/gem/v/better_errors.svg)](https://rubygems.org/gems/better_errors) [![Build Status](https://travis-ci.org/charliesome/better_errors.svg)](https://travis-ci.org/charliesome/better_errors) [![Code Climate](https://img.shields.io/codeclimate/github/charliesome/better_errors.svg)](https://codeclimate.com/github/charliesome/better_errors)
[![Build Status](https://travis-ci.org/BetterErrors/better_errors.svg)](https://travis-ci.org/BetterErrors/better_errors)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/6bc3e7d6118d47e6959b16690b815909)](https://www.codacy.com/app/BetterErrors/better_errors?utm_source=github.com&utm_medium=referral&utm_content=BetterErrors/better_errors&utm_campaign=Badge_Grade)
[![Coverage](https://coveralls.io/repos/github/BetterErrors/better_errors/badge.svg?branch=master)](https://coveralls.io/github/BetterErrors/better_errors?branch=master)
[![Gem Version](https://img.shields.io/gem/v/better_errors.svg)](https://rubygems.org/gems/better_errors)

# Better Errors

Better Errors replaces the standard Rails error page with a much better and more useful error page. It is also usable outside of Rails in any Rack app as Rack middleware.

![image](https://i.imgur.com/6zBGAAb.png)
![screenshot of Better Errors in action](https://i.imgur.com/6zBGAAb.png)

## Features

For screenshots of these features, [see the wiki](https://github.com/BetterErrors/better_errors/wiki).

* Full stack trace
* Source code inspection for all stack frames (with highlighting)
* Local and instance variable inspection
* Live REPL on every stack frame
* Live shell (REPL) on every stack frame
* Links directly to the source line in your editor
* Useful information in non-HTML requests

## Installation

Expand All @@ -18,87 +27,133 @@ Add this to your Gemfile:
```ruby
group :development do
gem "better_errors"
gem "binding_of_caller"
end
```

If you would like to use Better Errors' **advanced features** (REPL, local/instance variable inspection, pretty stack frame names), you need to add the [`binding_of_caller`](https://github.com/banister/binding_of_caller) gem by [@banisterfiend](https://twitter.com/banisterfiend) to your Gemfile:
[`binding_of_caller`](https://github.com/banister/binding_of_caller) is optional, but is necessary to use Better Errors' advanced features (REPL, local/instance variable inspection, pretty stack frame names).

```ruby
gem "binding_of_caller"
```
_Note: If you discover that Better Errors isn't working - particularly after upgrading from version 0.5.0 or less - be sure to set `config.consider_all_requests_local = true` in `config/environments/development.rb`._

This is an optional dependency however, and Better Errors will work without it.
### Optional: Set `EDITOR`

_Note: If you discover that Better Errors isn't working - particularly after upgrading from version 0.5.0 or less - be sure to set `config.consider_all_requests_local = true` in `config/environments/development.rb`._
For many reasons outside of Better Errors, you should have the `EDITOR` environment variable set to your preferred
editor.
Better Errors, like many other tools, will use that environment variable to show a link that opens your
editor to the file and line from the console.

## Security
By default the links will open TextMate-protocol links.

**NOTE:** It is *critical* you put better\_errors in the **development** section. **Do NOT run better_errors in production, or on Internet facing hosts.**
To see if your editor is supported or to set up a different editor, see [the wiki](https://github.com/BetterErrors/better_errors/wiki/Link-to-your-editor).

You will notice that the only machine that gets the Better Errors page is localhost, which means you get the default error page if you are developing on a remote host (or a virtually remote host, such as a Vagrant box). Obviously, the REPL is not something you want to expose to the public, but there may also be other pieces of sensitive information available in the backtrace.
### Optional: Set `BETTER_ERRORS_INSIDE_FRAME`

To poke selective holes in this security mechanism, you can add a line like this to your startup (for example, on Rails it would be `config/environments/development.rb`)
If your application is running inside of an iframe, or if you have a Content Security Policy that disallows links
to other protocols, the editor links will not work.

```ruby
BetterErrors::Middleware.allow_ip! ENV['TRUSTED_IP'] if ENV['TRUSTED_IP']
```
To work around this set `BETTER_ERRORS_INSIDE_FRAME=1` in the environment, and the links will include `target=_blank`,
allowing the link to open regardless of the policy.

Then run Rails like this:
_This works because it opens the editor from a new browser tab, escaping from the restrictions of your site._
_Unfortunately it leaves behind an empty tab each time, so only use this if needed._

```shell
TRUSTED_IP=66.68.96.220 rails s
```
## Security

Note that the `allow_ip!` is actually backed by a `Set`, so you can add more than one IP address or subnet.
**NOTE:** It is *critical* you put better\_errors only in the **development** section of your Gemfile.
**Do NOT run better_errors in production, or on Internet-facing hosts.**

**Tip:** You can find your apparent IP by hitting the old error page's "Show env dump" and looking at "REMOTE_ADDR".
You will notice that the only machine that gets the Better Errors page is localhost, which means you get the default error page if you are developing on a remote host (or a virtually remote host, such as a Vagrant box).
Obviously, the REPL is not something you want to expose to the public, and there may be sensitive information available in the backtrace.

**VirtualBox:** If you are using VirtualBox and are accessing the guest from your host's browser, you will need to use `allow_ip!` to see the error page.
For more information on how to configure access, see [the wiki](https://github.com/BetterErrors/better_errors/wiki/Allowing-access-to-the-console).

## Usage

If you're using Rails, there's nothing else you need to do.

If you're not using Rails, you need to insert `BetterErrors::Middleware` into your middleware stack, and optionally set `BetterErrors.application_root` if you'd like Better Errors to abbreviate filenames within your application.

Here's an example using Sinatra:
### Using without Rails.

```ruby
require "sinatra"
require "better_errors"

configure :development do
use BetterErrors::Middleware
BetterErrors.application_root = __dir__
end
If you're not using Rails, you need to insert `BetterErrors::Middleware` into your middleware stack, and optionally set `BetterErrors.application_root` if you'd like Better Errors to abbreviate filenames within your application.

get "/" do
raise "oops"
end
```
For instructions for your specific middleware, [see the wiki](https://github.com/BetterErrors/better_errors/wiki/Non-Rails-frameworks).

### Plain text
### Plain text requests

Better Errors will render a plain text error page when the request is an
`XMLHttpRequest` or when the `Accept` header does *not* include 'html'.

### Unicorn, Puma, and other multi-worker servers

Better Errors works by leaving a lot of context in server process memory. If
you're using a web server that runs multiple "workers" it's likely that a second
Better Errors works by leaving a lot of context in server process memory.
If you're using a web server that runs multiple "workers" it's likely that a second
request (as happens when you click on a stack frame) will hit a different
worker. That worker won't have the necessary context in memory, and you'll see
worker.
That worker won't have the necessary context in memory, and you'll see
a `Session Expired` message.

If this is the case for you, consider turning the number of workers to one (1)
in `development`. Another option would be to use Webrick, Mongrel, Thin,
or another single-process server as your `rails server`, when you are trying
to troubleshoot an issue in development.

### Changing the link to your editor

Better Errors includes a link to your editor for the file and line of code that is being shown.
By default, it uses your environment to determine which editor should be opened.
See [the wiki for instructions on configuring the editor](https://github.com/BetterErrors/better_errors/wiki/Link-to-your-editor).


## Set maximum variable size for inspector.

```ruby
# e.g. in config/initializers/better_errors.rb
# This will stop BetterErrors from trying to render larger objects, which can cause
# slow loading times and browser performance problems. Stated size is in characters and refers
# to the length of #inspect's payload for the given object. Please be aware that HTML escaping
# modifies the size of this payload so setting this limit too precisely is not recommended.
# default value: 100_000
BetterErrors.maximum_variable_inspect_size = 100_000
```

## Ignore inspection of variables with certain classes.

```ruby
# e.g. in config/initializers/better_errors.rb
# This will stop BetterErrors from trying to inspect objects of these classes, which can cause
# slow loading times and unneccessary database queries. Does not check inheritance chain, use
# strings not contants.
# default value: ['ActionDispatch::Request', 'ActionDispatch::Response']
BetterErrors.ignored_classes = ['ActionDispatch::Request', 'ActionDispatch::Response']
```

## Get in touch!

If you're using better_errors, I'd love to hear from you. Drop me a line and tell me what you think!

## Development

After checking out the repo, run `bundle install` to install the basic dependencies.

You can run the tests with the simplest set of dependencies using:

```rb
bundle exec rspec
```

To run specs for each of the dependency combinations, run:

```rb
bundle exec rake test:all
```

You can run specs for a specific dependency combination using:

```rb
BUNDLE_GEMFILE=gemfiles/pry09.gemfile bundle exec rspec
```

On CI, the specs are run against each gemfile on each supported version of Ruby.

## Contributing

1. Fork it
Expand Down
37 changes: 31 additions & 6 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,38 @@
require "bundler/gem_tasks"
require "rspec/core/rake_task"

namespace :test do
RSpec::Core::RakeTask.new(:with_binding_of_caller)
RSpec::Core::RakeTask.new(:test)
task :default => :test

without_task = RSpec::Core::RakeTask.new(:without_binding_of_caller)
without_task.ruby_opts = "-I spec -r without_binding_of_caller"
def gemfiles
@gemfiles ||= Dir[File.dirname(__FILE__) + '/gemfiles/*.gemfile']
end

task :all => [:with_binding_of_caller, :without_binding_of_caller]
def with_each_gemfile
gemfiles.each do |gemfile|
Bundler.with_clean_env do
puts "\n=========== Using gemfile: #{gemfile}"
ENV['BUNDLE_GEMFILE'] = gemfile
yield
end
end
end

task :default => "test:all"
namespace :test do
namespace :bundles do
desc "Install all dependencies necessary to test"
task :install do
with_each_gemfile { sh "bundle install" }
end

desc "Update all dependencies for tests"
task :update do
with_each_gemfile { sh "bundle update" }
end
end

desc "Test all supported sets of dependencies."
task :all => 'test:bundles:install' do
with_each_gemfile { sh "bundle exec rspec" rescue nil }
end
end
Loading

0 comments on commit d010b26

Please sign in to comment.