首页 > 解决方案 > 无法在不支持编码的对象上设置编码

问题描述

从云 9 迁移到 AWS 云 9。现在我在 GET 上收到错误...

在网上搜索了一些关于 postgresql 将 template1 更改为 template0 等的信息。没有成功。

2019-06-13 19:52:07 +0000 开始 GET "/" for 167.102.190.106

ArgumentError (cannot set encoding on non-encoding capable object)

Rendered /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.4ms)
  Rendered /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (0.7ms)
  Rendered /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.7ms)
  Rendered /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/actionpack-4.2.11.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (12.0ms)


Process exited with code: 0
[2019-06-13 19:52:44] INFO  going to shutdown ...

窗格死了

标签: ruby-on-rails

解决方案


简短的回答:

更改为不同的 Ruby 版本并为该版本重新安装 gem。

Ruby 2.4.7 和 Rails 4.2.11.1 对我有用,我需要更改的唯一其他 gem 版本是 bundler(从 2.0.2 到 1.17.3)

长答案:

在对 Ubuntu、Ruby、Rails 和我的项目 gemset 进行一系列版本升级后,我发现了同样的错误。有效的步骤(注意:您的确切版本可能会有所不同,具体取决于您的项目 gem。转到https://rubygems.org/并找到符合您需要的最新稳定版本/子版本,如您运行时的任何警告所述bundle install

切换到 Ruby 2.4.7

rvm install 2.4.7
rvm --default use 2.4.7 #use Ruby 2.4.7 and set it as the default

卸载 bundler(bundle install在更改 Ruby 版本后运行,它将显示 bundler < 2.0 是必需的)

gem uninstall bundler 

如果出现提示,您可能还需要卸载捆绑程序的全局安装,例如

gem uninstall -i /usr/local/rvm/gems/ruby-2.4.7@global bundler

安装兼容的捆绑器版本并运行它。如果您还有任何剩余的冲突,请使用https://rubygems.org/作为指南调整 Gemfile 中的版本。

gem install bundler -v 1.17.3
bundle install

我和你有同样的 Ruby/Rails 配对 - 2.6.3/4.2.11.1,并且得到了同样的错误信息。不会生成任何跟踪,因此很难使用已编译的 Ruby 库进行调试。

在寻求帮助时,我在这里遇到了一个不同的 gem,iconv 的错误报告(我的项目中没有):https ://github.com/ruby/iconv/issues/15 ,其中开发人员注释他们的 gem 在特定 Ruby 版本下使用时开始抛出该错误:

适用于 ruby​​ 2.6.0 preview1 和 2,不适用于 preview3 及更高版本,因此提交在 preview2 和 preview3 之间

以此为指导,我回到了上一个稳定的 Ruby 次要版本,2.4.7

在版本变化之前,我也发现我的系统中设置的位置为空,所以我设置LANG=en_CA.utf8了,但这没有效果。

其他尝试:

我在我的项目文件中搜索并没有找到字符串“无法在不支持编码的对象上设置编码”,这意味着错误是从 Ruby 核心文件或全局安装的 gem 中抛出的。所以我搜索:

grep -iRl "cannot set encoding on non-encoding capable object" /usr

并按预期取回了一组 Ruby 核心文件。虽然它们已经编译,所以我从https://github.com/ruby/ruby下载了 Ruby 源文件并搜索了源代码。

在 encoding.c 中的函数中抛出错误:

enc_set_index(VALUE obj, int idx)
{
    if (!enc_capable(obj)) {
        rb_raise(rb_eArgError, "cannot set encoding on non-encoding capable object");
    }

    if (idx < ENCODING_INLINE_MAX) {
    ENCODING_SET_INLINED(obj, idx);
    return;
    }
    ENCODING_SET_INLINED(obj, ENCODING_INLINE_MAX);
    rb_ivar_set(obj, rb_id_encoding(), INT2NUM(idx));
}

基于 encoding.c 中其他地方的对象类型测试

static inline int
enc_capable(VALUE obj)
{
    if (SPECIAL_CONST_P(obj)) return SYMBOL_P(obj);
    switch (BUILTIN_TYPE(obj)) {
      case T_STRING:
      case T_REGEXP:
      case T_FILE:
      case T_SYMBOL:
    return TRUE;
      case T_DATA:
    if (is_data_encoding(obj)) return TRUE;
      default:
    return FALSE;
    }
}

如果您想完全诊断问题,您可以跟踪 Ruby 源代码中的调用和定义来查看发生了什么,和/或在enc_set_index函数中添加自定义回溯日志调用,编译这个自定义版本的 Ruby,然后安装它为您的项目提供更充实的错误消息。但是……你呢?

结论:

有一些不兼容的 Ruby、Rails 版本和一些导致错误的 gem。寻找确切的 gem 并不值得——更改 Ruby 版本本身要容易得多。前面提到的iconvgem 用更新的版本 ( iconv-1.0.6) 修复了错误,大概当我继续 gem 和系统版本更新时,我会发现更高版本的组合不会引发错误。


推荐阅读