【问题标题】:Rails app: ArgumentError (invalid byte sequence in UTF-8) when connecting to production databaseRails 应用程序:连接到生产数据库时出现 ArgumentError(UTF-8 中的字节序列无效)
【发布时间】:2022-01-22 11:25:38
【问题描述】:

我正在设置一个小型 Rails 内部网应用程序,并在部署过程中遇到了一个令人困惑的错误。 staging 应用程序部署良好,我可以访问各种 API 端点,这些端点显示有关 Postgres 数据库内容的基本信息(某个表上的 COUNT 等)

但是当我将同一个应用程序部署到生产环境时,第一次尝试运行任何数据库查询时,它会触发 500 响应并记录此异常:

ArgumentError (invalid byte sequence in UTF-8)

我假设这个错误告诉我连接到数据库时出现问题,或者可能是解析数据库查询返回的数据时出现问题,但没有显示堆栈跟踪,我无法找出问题所在。我已经对database.yml 中的连接设置进行了双重和三重检查,它(在暂存和生产中)设置了从 Rails 加密密钥中获取的数据库 URL。

数据库 URL 采用标准格式,与我在其他几个 Rails 应用程序中使用的相同:postgres://username:password@hostname:5432/dbname

我可以使用psql 直接连接到这些数据库URL 中的任何一个都没有问题。问题不在于加密的机密文件,因为即使我将数据库 URL 硬编码为 database.yml,它仍然存在。

我应该从这里去哪里?找出此错误根源的最佳做法是什么?

【问题讨论】:

    标签: ruby-on-rails database postgresql


    【解决方案1】:

    经过一番折腾,我发现生产数据库密码包含%# 等特殊字符,为了让Rails 正确解析数据库URL,必须对其进行转义。暂存数据库密码不包含此类字符,因此我可以将密码包含在数据库 URL 中而无需任何转义。但生产密码确实如此,所以我需要对其进行转义并将 that 值放入 DB URL,而不是原始密码。

    URI.encode("abc123#%")
    => "abc123%23%25"
    database_url = "postgres://username:abc123%23%25@hostname:5432/dbname"
    

    当 Rails 尝试解析 database.yml 中的连接凭据时,如果遇到任何此类未转义的字符,它可能会给您提供几个无用的低级异常之一,例如 ArgumentError (invalid byte sequence in UTF-8),通常没有记录堆栈跟踪,所以您可能需要手动捕获此错误并打印出堆栈跟踪,以确认它确实是解析连接 URL 的问题。

    我学到的教训:每当您使用postgres:// URL 时,请务必使用URI.escape() 转义您的数据库密码!如果您的应用首次尝试连接到数据库时遇到奇怪的字符串解析相关错误,请仔细检查您的 postgres:// URL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-03
      • 2015-07-04
      • 2014-01-09
      • 2016-07-05
      • 2013-08-20
      • 1970-01-01
      • 2012-06-19
      • 2017-03-31
      相关资源
      最近更新 更多