Home > Mobile >  FrozenError with ruby 3.1 upgrade
FrozenError with ruby 3.1 upgrade

Time:08-16

I was working on upgrading the ruby version of my application from 2.6.7 to 3.1.2 but while running the test cases I am encountering the FrozenError. Below is the proper error stack.

{
  "status": 500,
  "error": "Internal Server Error",
  "exception": "#\u003cFrozenError: can't modify frozen String: \"\"\u003e",
  "traces": {
    "Application Trace": [
      {
        "exception_object_id": 23180,
        "id": 5,
        "trace": "app/controllers/v2/tags_controller.rb:20:in `create'"
      },
      {
        "exception_object_id": 23180,
        "id": 13,
        "trace": "app/helpers/v2_security_helper.rb:25:in `set_current_integration'"
      },
      {
        "exception_object_id": 23180,
        "id": 40,
        "trace": "config/initializers/versioning.rb:32:in `call'"
      }
    ],
    "Framework Trace": [
      {
        "exception_object_id": 23180,
        "id": 0,
        "trace": "http (0.8.14) lib/http/response/body.rb:41:in `force_encoding'"
      },
      {
        "exception_object_id": 23180,
        "id": 1,
        "trace": "http (0.8.14) lib/http/response/body.rb:41:in `to_s'"
      },
      {
        "exception_object_id": 23180,
        "id": 2,
        "trace": "json (2.6.2) lib/json/common.rb:216:in `initialize'"
      },
      {
        "exception_object_id": 23180,
        "id": 3,
        "trace": "json (2.6.2) lib/json/common.rb:216:in `new'"
      },
      {
        "exception_object_id": 23180,
        "id": 4,
        "trace": "json (2.6.2) lib/json/common.rb:216:in `parse'"
      },
      {
        "exception_object_id": 23180,
        "id": 6,
        "trace": "apipie-rails (0.6.0) lib/apipie/dsl_definition.rb:286:in `call'"
      },
      {
        "exception_object_id": 23180,
        "id": 7,
        "trace": "apipie-rails (0.6.0),

Below is the code mentioned in the error stack

def create
  validate_batch_information_params(create_params[:batch_information])

  tag_resource = TagResource.new(create_params).create!
  tag_creation = JSON.parse(tag_resource.body)  **This line causing error**

  case tag_resource.status
  when 201

I tried fixing this by adding # frozen_string_literal: false at the top of the file as well as adding .dup in the line that is causing the error but that did not resolve the error.

I suspect this is due to some gem issue because this issue arose after upgrading the ruby version to 3.1.2, so I am also attaching a snapshot of my gemfile.

source 'https://rubygems.org'

# please keep these in alphabetical order
gem 'active_model_serializers',   '0.10.0'
gem 'apipie-rails',               '0.6.0'
gem 'aws-sdk-cognitoidentityprovider', '~> 1'
gem 'aws-sdk-ec2',                '~> 1'
gem 'aws-sdk-s3',                 '~> 1'
gem 'cancancan',                  '3.3.0'
gem 'exception_notification',     '4.0.1'
gem 'feature',                    '~> 1.3.0'
gem 'foreman',                    '0.87.0'
gem 'http',                       '~> 0.8.12'
gem 'jbuilder',                   '~> 2.0'
gem 'json',                       '2.6.2'
gem 'logstasher',                 '0.6.5'
gem 'matrix',                     '~> 0.4.2'
gem 'mysql2',                     '~> 0.5'
gem 'net-smtp',                   '~> 0.3.1'
gem 'nokogiri',                   '~> 1.10'
gem 'psych',                      '< 4'
gem 'rails',                      '6.1.6'
gem 'responders',                 '~> 3.0'
gem 'rollout',                    '~> 2.1.0'
gem 'slack-notifier',             '1.2.1', :require => false
gem 'thread_safe',                '0.3.6'
gem 'unicorn',                    '4.8.3'
gem 'webrick',                    '~> 1.7'

group :doc do
  # bundle exec rake doc:rails generates the API under doc/api.
  gem 'sdoc', :require => false
end

group :development do
  gem 'annotate',                 '>=2.6.0'
  gem 'bcrypt_pbkdf',             '1.1.0'
  gem 'capistrano',               '3.4'
  gem 'capistrano-bundler',       '1.1.2'
  gem 'capistrano-rvm',           '0.1.1'
  gem 'capistrano-slackify',      '2.6.0', :require => false
  gem 'ed25519',                  '1.3.0'
end

group :test do
  gem 'codeclimate-test-reporter', :require => nil
  gem 'minitest-rails', '~> 6.1'
  gem 'minitest-reporters'
  gem 'minitest-spec-rails', '6.0.1'
  gem 'mocha', '1.2.1', :require => 'mocha/api'
  gem 'net-imap', '~> 0.2.3'
  gem 'net-pop', '0.1.1'
  gem 'rails-perftest'
  gem 'ruby-prof', '0.14.2'
  gem 'shoulda', '~> 4.0.0'
  gem 'shoulda-matchers',   '~> 4.5'
  gem 'simplecov', :require => false
  gem 'test-unit'
  gem 'timecop'
end

group :development, :test, :ci do
  gem 'asciidoctor'
  gem 'asciidoctor-pdf'
  gem 'asciidoctor-diagram'
  gem 'brakeman',                   '~> 5.0'
  gem 'bullet'
  gem 'coderay'
  gem 'factory_bot_rails',          '~> 6.2'
  gem 'pry',                        '~> 0.13.1', :require => false
  gem 'pry-byebug',                 '3.9.0', :require => false
  gem 'pry-stack_explorer',         '0.4.9.1', :require => false
  gem 'rubocop',                    '0.26.1', :require => false
  gem 'terminal-notifier',          :require => false
  gem 'webmock',                    '1.20.4', :require => false
end

group :production, :qa, :integration, :staging do
  gem 'ddtrace',                      '~> 1.1'
  gem 'lograge',                      '~> 0.12'
end

I've been stuck at this for about two weeks now, please let me know if anybody find anything.

CodePudding user response:

You have gem 'http', '~> 0.8.12' in your Gemfile, that's pulled in version 0.8.14. That's from August 2015. Upgrade that by removing the version pin and allowing it to be upgraded to the latest. Even if you have to fix something else (unlikely) that's just something you'll need to deal with because that 0.8 version is WAY too old to use.

CodePudding user response:

The issue is that force_encoding is being called on a frozen string. I have modified the HTTP::Response::Body code to call the force_encoding method on a dup of original string, so in this should work. Just place the code below in the initialisers or anywhere before the controller is called.

module HTTP
  class Response
    class Body
      def to_s
        return @contents if @contents

        fail StateError, "body is being streamed" unless @streaming.nil?

        begin
          @streaming = false
          @contents = "".force_encoding(Encoding::UTF_8)
          while (chunk = @client.readpartial)
            @contents << chunk.dup.force_encoding(Encoding::ASCII_8BIT)
          end
        rescue
          @contents = nil
          raise
        end

        @contents
      end
    end
  end
end
  • Related