LoginSignup
3
5

More than 5 years have passed since last update.

Redmine カスタムクエリが500 ActionView::Template::Error ("XXX" from ASCII-8BIT to UTF-8) になるときの対処方法

Last updated at Posted at 2015-10-11

発生した環境

  • Bitnami Redmine Stack (Windows版) 1.4 から 3.1.1 へのアップグレード後
  • 通常のIssue作成、閲覧は問題ない
  • カスタムクエリだけ 500 Internal Error

原因

  • production.log によるとVIEWの表示で ASCII-8BIT から UTF-8 へ変換できないとのこと。
production.log
Started GET "/redmine/projects/a/issues?query_id=1" for 192.168.XX.XX at 2015-XX-XX XX:XX:XX +0900
Processing by IssuesController#index as HTML
  Parameters: {"query_id"=>"1", "project_id"=>"a"}
  Current user: User (id=1)
  Rendered queries/_filters.html.erb (10.0ms)
  Rendered issues/index.html.erb within layouts/base (16.0ms)
Completed 500 Internal Server Error in 261ms (ActiveRecord: 101.0ms)

ActionView::Template::Error ("\xE4" from ASCII-8BIT to UTF-8):
     7: $(document).ready(function(){
     8:   initFilters();
     9:   <% query.filters.each do |field, options| %>
    10:   addFilter("<%= field %>", <%= raw_json query.operator_for(field) %>, <%= raw_json query.values_for(field) %>);
    11:   <% end %>
    12: });
    13: <% end %>
  app/helpers/application_helper.rb:1076:in `raw_json'
  app/views/queries/_filters.html.erb:10:in `block (2 levels) in _app_views_queries__filters_html_erb__85224075_77320944'
  app/views/queries/_filters.html.erb:9:in `each'
  app/views/queries/_filters.html.erb:9:in `block in _app_views_queries__filters_html_erb__85224075_77320944'
  app/views/queries/_filters.html.erb:1:in `_app_views_queries__filters_html_erb__85224075_77320944'
  app/views/issues/index.html.erb:19:in `block in _app_views_issues_index_html_erb___72240600_77564676'
  app/views/issues/index.html.erb:11:in `_app_views_issues_index_html_erb___72240600_77564676'
  app/controllers/issues_controller.rb:77:in `block (2 levels) in index'
  app/controllers/issues_controller.rb:76:in `index'
  lib/redmine/sudo_mode.rb:63:in `sudo_mode'

app/helpers/application_helper.rb にある raw_json が問題を起こしている様子。

app/helpers/application_helper.rb
  # Helper to render JSON in views
  def raw_json(arg)
    arg.to_json.to_s.gsub('/', '\/').html_safe
  end

arg.inspect してみるとちゃんと UTF-8 だと判定されたりASCII-8BIT (例えば"\xE4")と判定されたり混ざっていた。rubyでは「文字コードの違うものどうしを結合できない」とエラーになってしまう。

対処(とりあえず)

呼び出し元で対処するか、このraw_jsonで対応すべきか正直迷ったのですが。
来たものを片っ端からUTF-8にしてしまうことで逃げる。

app/helpers/application_helper.rb
  # Helper to render JSON in views
  def raw_json(arg)
    arg = force_utf8_strings(arg)      # add
    arg.to_json.to_s.gsub('/', '\/').html_safe
  end

ファイルの末(Private メソッドの並び)

app/helpers/application_helper.rb
private

# (略)

# add
  def force_utf8_strings(arg)
    if arg.is_a?(String)
      arg.dup.force_encoding('UTF-8')
    elsif arg.is_a?(Array)
      arg.map do |a|
        force_utf8_strings(a)
      end
    elsif arg.is_a?(Hash)
      arg = arg.dup
      arg.each do |k,v|
        arg[k] = force_utf8_strings(v)
      end
      arg
    else
      arg
    end
  end

これでエラーは出なくなりました。
実は force_utf8_strings は app/models/setting.rb にあるPrivateメソッドをコピーしたもの。
同じコードが二箇所にあることになるので、原則的に良い方法じゃないですよね・・・。
こういった場合はどこに配置するのがいいのでしょう。

※2018/07/05 追記
こちらの方が対応されたように、もう一か所修正が必要なようです。
https://qiita.com/sugasaki/items/296a2e1f8101826ce588

なお最新版のRedmineでも同様の事象が起きる場合の対処ですが
上記パッチ対応後にカスタムクエリーを修正・保存しなおすと、カスタムクエリ上の条件文字列データがUTF-8で保存しなおされるので次からエラーがでなくなることを確認しました。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5