code_aks
code_aks

Reputation: 2074

How do I fix: ArgumentError: invalid byte sequence in UTF-8?

I am getting this type of error in the logs :

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    

During update, it rollbacks without giving any error (not execute else condition)

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

How can I fix or handle this type of request?

Upvotes: 1

Views: 2908

Answers (1)

Masa Sakano
Masa Sakano

Reputation: 2267

Your question is how to handle this type of request or error. So here is my suggestion of a general strategy.

First, do your homework. You could easily find this past question, for example. If you have tried the way already but found it did not work, you should have described what you did and what did not work in your question.

Now, I am assuming you can reproduce the case or at least you can expect you will encounter the same problem in near future (or you can wait till then) so you will have a more chance to pin down the problem next time. If you know what parameters caused the error, I guess you can reproduce the case in your development environment. However, if not, it is more tricky to pin down — it heavily depends how much information about the error and input you have and what development environment you can use, and my answer does not cover the case.

The first objective should be to pin down which command (method) exactly in your code caused an error. Did it happen just inside Rails or did your DB raise an error? In your specific case, did it occur at Step.find_by or @step.update or else? What is steps_params? It seems like a method you have defined. Are you sure steps_params is working as expected? (You may be sure, but we don't know…)

A convenient way to find it out is simply to insert logger.debug (or logger.error) etc before and after each sentence. In doing it, it is recommended to split a sentence into smaller units in some cases. For example, steps_params and update() should be separated, such as (in the simplest case),

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
  # ……

Obviously you can (and perhaps should) log more detailed information, such as, res_steps_params.inspect, and you may also enclose a part with a begin-rescue clause so that you can get the detailed infromation about the exception and log it. Also, I can recommend to split update into 2 parts – substitutions and save – to find out exactly what action and parameter cause a problem.

Once you have worked out which of DB or Rails or something before (like HTTP-server or Client-browser) is to blame and which parameter causes a problem, then you can proceed to the next stage. The error message suggests it is a character-encoding issue. Is the character encoding of a string invalid (as a UTF-8), or wrongly recognised by Rails (which might be not a fault of Rails but of the client), or not recognised correctly by the DB?

Wherever the problem lies, it is usually (though not always!) possible to fix or circumvent character-encoding problems with Ruby (Rails). The Ruby methods of String#encode, String#encoding, and String#force_encoding would be useful to diagnose and perhaps fix the problem.

As an added note, it can be useful, if possible in your environment, to browse the logfile of your DB (PostgreSQL?) to find out which query passed from Rails to the DB caused a problem (if a query was indeed passed to them!). Alternatively, Rails Gem SQL Query Tracker might be handy to know what queries your Rails app create (though I have never used it and so can't tell much.)

At the end of the day, when a code misbehaves mysteriously, I am afraid only the sure way to solve is to narrow down the problematic clause or parameter step by step. Good luck!

Upvotes: 2

Related Questions