我该如何解决:ArgumentError:UTF-8中的无效字节序列?

时间:2019-03-05 07:48:57

标签: ruby-on-rails character-encoding

我在日志中遇到这种类型的错误:

Parameters: {"id"=>"4", "step"=>{"documents_attributes"=>{"0"=>
  {"file"=>"\x89PNG\r\n\u001A\n\u0000\u0000\u0000\rIHDR\u0000\..."}}}}

 def update
   @step = Step.find_by(id: params[:id])
   if @step.update(steps_params)
     render :json => @step
   else
     render :json => { :responseStatus => 402,
       :responseMessage => @step.errors.full_messages.first} 
   end
 end    

在更新过程中,它回滚而没有给出任何错误(不执行其他条件)

ArgumentError (invalid byte sequence in UTF-8):
(0.2ms)  ROLLBACK

如何解决或处理此类请求?

1 个答案:

答案 0 :(得分:2)

您的问题是如何处理此类请求或错误。所以这是我对一般策略的建议。

首先,做功课。例如,您可以轻松找到this past question。如果您已经尝试过该方法,但发现它不起作用,则应该说明您在问题中做了什么和什么没有解决。

现在,我假设您可以重审此案,或者至少可以期望您不久以后会遇到相同的问题(或者您可以等到那时),以便下次有更多机会解决该问题。如果您知道导致错误的参数是什么,我想您可以在开发环境中重现这种情况。但是,如果不能,则很难确定-它在很大程度上取决于有关错误和输入的信息以及可以使用的开发环境的信息,而我的回答并不涵盖这种情况。

第一个目标应该是确切确定代码中哪个命令(方法)导致了错误。它只是在Rails内部发生还是您的数据库引发了错误? 在您的特定情况下,它是否发生在Step.find_by@step.update上?什么是steps_params?似乎是您已定义的方法。您确定steps_params工作正常吗? (您可能会确定,但我们不知道...)

一种简单的查找方法是在每个句子的前后插入logger.debug(或logger.error)等。为此,建议在某些情况下将句子拆分为较小的单位。例如,steps_paramsupdate()应该分开,例如(在最简单的情况下)

logger.debug 'Before steps_params'
res_steps_params = steps_params
logger.debug 'Before update'
res_update = @step.update(res_steps_params)
logger.debug 'Before if'
if res_update
  # ……

很显然,您可以(也许应该)记录更详细的信息,例如res_steps_params.inspect,并且您还可以用begin-rescue子句将零件括起来,以便您可以获取有关异常的详细信息并记录它。另外,我建议将update分为两部分-替换和save –准确找出导致问题的操作和参数。

一旦确定了应该归咎于哪个DB或Rails或某些东西(如HTTP服务器或Client-browser)以及哪个参数导致了问题,那么就可以进入下一个阶段。该错误消息表明这是一个字符编码问题。字符串的字符编码是无效的(作为UTF-8),还是被Rails错误地识别(这可能不是Rails的错误,而是客户端的错误),或者未被数据库正确识别?

无论问题出在哪里,通常(尽管并非总是如此!)都可以使用Ruby(Rails)来解决或规避字符编码问题。 String#encodeString#encodingString#force_encoding的Ruby方法对于诊断甚至解决问题很有用。

作为补充,如果可能,在您的环境中,浏览数据库的日志文件(PostgreSQL?)以找出哪个是从Rails传递给数据库的查询引起了问题(如果确实是一个查询,则很有用)。传递给他们!)。另外,Rails Gem SQL Query Tracker可以很方便地了解您的Rails应用创建的查询(尽管我从未使用过,所以不能说太多。)

最终,当代码神秘地发生异常行为时,恐怕唯一确定的解决方法是逐步缩小有问题的子句或参数的范围。祝你好运!