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

Properly fallback when ERB column can't be computed #48184

Merged
merged 1 commit into from
May 18, 2023

Conversation

casperisfine
Copy link
Contributor

Fix: #48173

If for some reason the column identification fails, we should fallback to the old error rendering with only line information.

cc @tenderlove

FYI @jasonkim

Fix: rails#48173

If for some reason the column identification fails, we should
fallback to the old error rendering with only line information.
@rails-bot rails-bot bot added the actionview label May 10, 2023
@obie
Copy link

obie commented May 11, 2023

This can't be merged fast enough.

@byroot
Copy link
Member

byroot commented May 11, 2023

Sorry, I and @tenderlove are travelling right now, so it may take a few days. In the meantime you can point your Gemfile at this branch

@obie
Copy link

obie commented May 11, 2023 via email

@tenderlove
Copy link
Member

Looks good, thanks. Though, I wonder why it can't identify the location. I'll merge this, but I think we should find the reason it can't identify the column.

@tenderlove tenderlove merged commit e89664b into rails:main May 18, 2023
9 checks passed
tenderlove added a commit to tenderlove/rails that referenced this pull request May 24, 2023
Text tokens may be conditionally appended to the output buffer.  For
example if we have a template like this:

```erb
<h1>Oh no!</h1>
This template has a runtime error
<b>
  <% if true %>
    <%= method_that_does_not_exist %>
  <% end %>
</b>
Yikes!
```

In the above case, a string literal (`"    "`) will be conditionally
appended to the output buffer with some code like below:

```ruby
@output_buffer.safe_append='    '.freeze
```

This commit teaches text tokens (string literals) to scan forward in the
compiled template until it finds the literal, thereby skipping the code
generated for appending to the output buffer.

Related to:

* Bug: rails#48173
* PR: rails#48184
casperisfine pushed a commit to Shopify/rails that referenced this pull request Jun 1, 2023
@obie
Copy link

obie commented Jun 6, 2023

Got rid of my hotfix since it had stopped working anyway and this problem is still present in current HEAD 0de4017

Certain kinds of exceptions will get the 500 page in development mode instead of normal exception screen with console. Now with no known hotfix.

Heads up @casperisfine @tenderlove @zarqman

@byroot
Copy link
Member

byroot commented Jun 6, 2023

@obie can you share the exception and backtrace? Without it we can't know where the problem might be.

@jpcody
Copy link
Contributor

jpcody commented May 12, 2024

Update: Shopify/better-html#121 was our issue.


I'm not @obie, but I'm seeing the same after attempting to upgrade our app from 7.0.8 to 7.1.3.2 (or 7.1.0 for that matter). Within ActionDispatch::DebugExceptions#render_for_browser_request, the call to create_template fails within the call to ActionView::Template::Handlers::ERB#translate_location.

In my case, backtrace_location.lineno has the wrong line number (it returns 33, and my error is on line 31). Line 33 is the correct source of the error, and line 31 is an empty line. Parsing the empty line fails, and public/500.html renders.

Here's how the template in question is set up. In every failure case, the exception page doesn't render, but it's often for different reasons (failure to tokenize the string, exception in find_offset, different exception in find_offset).

In this scenario, I'm raising exceptions at different spots to see what the source location reports.

<%# boom - line_number: 1, exception page renders %>
<%= render_breadcrumb_header(@breadcrumbs) do %>
  <%# boom - line_number: 2, exception page can't render %>
  <% if policy(Report).create? %>
    <%# boom - line_number: 2, exception page can't render %>
    <%= sidebar_button_to t("reports.new_button"),
      new_selector_reports_path,
      modifier: "light" %>
    <%# boom - line_number: 2, exception page can't render %>
  <% end %>
  <%# boom - line_number: 2, exception page can't render %>
<% end %>
<%# boom - line_number: 15, exception page can't render %>

Interestingly, if I change the sidebar_button_to method call to be a single line, the line numbers become correct, and this entire problem becomes moot for us. The issue is also addressed if I wrap the method call in parens.

I chased down a red herring that might or might not be a problem with tokenizing ERB strings, so I'll tuck it away here…

But whether I pass the contents of line 33 or line 31 to ERB::Util.tokenize, I get a NotImplementedError. The line intended to raise the error is:

# Trigger an i18n error from a line in a top-level `index.html.erb` template
        <h2 class="container__title"><%= t(".ttttemplates_header") %></h2>

And in a console, I get the following results

# Trigger the same exception manually
> ERB::Util.tokenize("        <h2 class=\"container__title\"><%= t(\".ttttemplates_header\") %></h2>")
# NotImplementedError: NotImplementedError
# from /Users/jpcody/.asdf/installs/ruby/3.3.1/lib/ruby/gems/3.3.0/gems/activesupport-7.1.3.2/lib/active_support/core_ext/erb/util.rb:173:in `tokenize'

# Still unsuccessful with a proper reference
> > ERB::Util.tokenize("        <h2 class=\"container__title\"><%= t(\".templates_header\") %></h2>")

# Still unsuccessful with simpler HTML
> ERB::Util.tokenize("<h2><%= t(\".templates_header\") %></h2>")

# Now successful without trailing content
> ERB::Util.tokenize("<h2><%= t(\".templates_header\") %>")

It almost seems like the string scanner in the ERB util can't handle anything after the ERB tags.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exception in ERB template does not render exception view properly
5 participants