Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 1548 (sinatra) Describe raise_errors better in README and configuration #305

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 65 additions & 2 deletions _includes/README.html
Original file line number Diff line number Diff line change
Expand Up @@ -1905,9 +1905,13 @@ <h3 id="available-settings">Available Settings</h3>

<dt>raise_errors</dt>
<dd>
Raise exceptions (will stop application). Enabled by default when
Raise unhandled errors (will stop application). Enabled by default when
<tt>environment</tt> is set to <tt>"test"</tt>, disabled otherwise.
</dd>
<dd>
Any explicitly defined error handlers always override this setting. See
the "Error" section below.
</dd>

<dt>run</dt>
<dd>
Expand Down Expand Up @@ -2052,14 +2056,21 @@ <h3 id="error">Error</h3>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">set</span> <span class="ss">:show_exceptions</span><span class="p">,</span> <span class="ss">:after_handler</span>
</code></pre></div></div>

<p>A catch-all error handler can be defined with <code>error</code> and a block:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">error</span> <span class="k">do</span>
<span class="s1">'Sorry there was a nasty error'</span>
<span class="k">end</span>
</code></pre></div></div>

<p>The exception object can be obtained from the <code>sinatra.error</code> Rack variable:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">error</span> <span class="k">do</span>
<span class="s1">'Sorry there was a nasty error - '</span> <span class="o">+</span> <span class="n">env</span><span class="p">[</span><span class="s1">'sinatra.error'</span><span class="p">].</span><span class="nf">message</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Custom errors:</p>
<p>Pass an error class as an argument to create handlers for custom errors:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">error</span> <span class="no">MyCustomError</span> <span class="k">do</span>
<span class="s1">'So what happened was...'</span> <span class="o">+</span> <span class="n">env</span><span class="p">[</span><span class="s1">'sinatra.error'</span><span class="p">].</span><span class="nf">message</span>
Expand Down Expand Up @@ -2100,6 +2111,58 @@ <h3 id="error">Error</h3>
running under the development environment to display nice stack traces
and additional debugging information in your browser.</p>

<h3 id="behavior-with-raiseerrors-option">Behavior with <code>raise_errors</code> option</h3>

<p>When <code>raise_errors</code> option is <code>true</code>, errors that are unhandled are raised
outside of the application. Additionally, any errors that would have been
caught by the catch-all error handler are raised.</p>

<p>For example, consider the following configuration:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># First handler</span>
<span class="n">error</span> <span class="no">MyCustomError</span> <span class="k">do</span>
<span class="s1">'A custom message'</span>
<span class="k">end</span>

<span class="c1"># Second handler</span>
<span class="n">error</span> <span class="k">do</span>
<span class="s1">'A catch-all message'</span>
<span class="k">end</span>
</code></pre></div></div>

<p>If <code>raise_errors</code> is <code>false</code>:</p>

<ul>
<li>When <code>MyCustomError</code> or descendant is raised, the first handler is invoked.
The HTTP response body will contain <code>"A custom message"</code>.</li>
<li>When any other error is raised, the second handler is invoked. The HTTP
response body will contain <code>"A catch-all message"</code>.</li>
</ul>

<p>If <code>raise_errors</code> is <code>true</code>:</p>

<ul>
<li>When <code>MyCustomError</code> or descendant is raised, the behavior is identical to
when <code>raise_errors</code> is <code>false</code>, described above.</li>
<li>When any other error is raised, the second handler is <em>not</em> invoked, and
the error is raised outside of the application.
<ul>
<li>If the environment is <code>production</code>, the HTTP response body will contain
a generic error message, e.g. <code>"An unhandled lowlevel error occurred. The
application logs may have details."</code>
</li>
<li>If the environment is not <code>production</code>, the HTTP response body will contain
the verbose error backtrace.</li>
<li>Regardless of environment, if <code>show_exceptions</code> is set to <code>:after_handler</code>,
the HTTP response body will contain the verbose error backtrace.</li>
</ul>
</li>
</ul>

<p>In the <code>test</code> environment, <code>raise_errors</code> is set to <code>true</code> by default. This
means that in order to write a test for a catch-all error handler,
<code>raise_errors</code> must temporarily be set to <code>false</code> for that particular test.</p>

<h2 id="rack-middleware">Rack Middleware</h2>

<p>Sinatra rides on <a href="https://rack.github.io/">Rack</a>, a minimal standard
Expand Down
7 changes: 4 additions & 3 deletions _includes/rack-protection-readme.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ <h2 id="cookie-tossing">Cookie Tossing</h2>
<p>Prevented by:</p>

<ul>
<li><a href="http://www.sinatrarb.com/protection/cookie_tossing"><code>Rack::Protection::CookieTossing</code></a> (not included by <code>use Rack::Protection</code>)</li>
<li>
<a href="http://www.sinatrarb.com/protection/cookie_tossing"><code>Rack::Protection::CookieTossing</code></a> (not included by <code>use Rack::Protection</code>)</li>
</ul>

<h2 id="ip-spoofing">IP Spoofing</h2>
Expand All @@ -114,9 +115,9 @@ <h1 id="installation">Installation</h1>

<h1 id="instrumentation">Instrumentation</h1>

<p>Instrumentation is enabled by passing in an instrumenter as an option.
<p>Instrumentation is enabled by passing in an instrumenter as an option.</p>

<pre><code> use Rack::Protection, instrumenter: ActiveSupport::Notifications
<pre><code>use Rack::Protection, instrumenter: ActiveSupport::Notifications
</code></pre>

<p>The instrumenter is passed a namespace (String) and environment (Hash). The namespace is ‘rack.protection’ and the attack type can be obtained from the environment key ‘rack.protection.attack’.</p>
Expand Down
16 changes: 13 additions & 3 deletions configuration.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,22 @@ default in classic style apps. Disable with:
Boolean specifying whether exceptions raised from routes and filters should
escape the application. When disabled, exceptions are rescued and mapped to
error handlers which typically set a 5xx status code and render a custom
error page. Enabling the `:raise_errors` setting causes exceptions to be
raised outside of the application where it may be handled by the server
error page. Enabling the `:raise_errors` setting causes unhandled exceptions
to be raised outside of the application where it may be handled by the server
handler or Rack middleware, such as [`Rack::ShowExceptions`][se] or
[`Rack::MailExceptions`][me].

[se]: http://www.rubydoc.info/github/rack/rack/Rack/ShowExceptions
[me]: https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/mailexceptions.rb

The behavior of `:raise_errors` for unhandled errors depends on environment
when set to `true`. If the environment is `production`, the HTTP response body
will contain a generic error message, e.g. `"An unhandled lowlevel error
occurred. The application logs may have details."` If the environment is not
`production`, the HTTP response body will contain the verbose error backtrace.
Comment on lines +249 to +253
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder of this isn't describing the behaviour of Puma? (which is about to be tweaked with puma/puma#3094)


In the `test` environment, `raise_errors` is set to `true` by default.

### `:lock` - ensure single request concurrency with a mutex lock

Sinatra can be used in threaded environments where more than a single
Expand All @@ -260,4 +268,6 @@ The `:lock` setting is disabled by default.

Enable error pages that show backtrace and environment information when
an unhandled exception occurs. Enabled in development environments by
default.
default. Regardless of environment, if `show_exceptions` is set to
`:after_handler`, the HTTP response body will contain the verbose error
backtrace.