rollbar 1.5.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +66 -8
- data/CHANGELOG.md +17 -1
- data/README.md +17 -7
- data/lib/generators/rollbar/templates/initializer.rb +4 -3
- data/lib/rollbar.rb +35 -34
- data/lib/rollbar/configuration.rb +2 -0
- data/lib/rollbar/core_ext/basic_socket.rb +7 -0
- data/lib/rollbar/encoding.rb +21 -0
- data/lib/rollbar/encoding/encoder.rb +54 -0
- data/lib/rollbar/encoding/legacy_encoder.rb +18 -0
- data/lib/rollbar/json.rb +41 -0
- data/lib/rollbar/request_data_extractor.rb +1 -1
- data/lib/rollbar/tasks/rollbar.cap +2 -0
- data/lib/rollbar/truncation/mixin.rb +1 -1
- data/lib/rollbar/version.rb +1 -1
- data/rollbar.gemspec +1 -2
- data/spec/requests/home_spec.rb +1 -1
- data/spec/rollbar/delay/resque_spec.rb +1 -1
- data/spec/rollbar/encoding/encoder_spec.rb +63 -0
- data/spec/rollbar/json_spec.rb +29 -0
- data/spec/rollbar/truncation/frames_strategy_spec.rb +3 -3
- data/spec/rollbar/truncation/min_body_strategy_spec.rb +3 -3
- data/spec/rollbar/truncation/strings_strategy_spec.rb +6 -6
- data/spec/rollbar_bc_spec.rb +24 -21
- data/spec/rollbar_spec.rb +32 -4
- data/spec/spec_helper.rb +6 -0
- data/spec/support/fixture_helpers.rb +1 -1
- metadata +94 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4dd960fba2b048a769f6de1c197af1db2b8ac13f
|
4
|
+
data.tar.gz: 40540eb9711481d7340bfe7f2714b9ef2aa59c5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8146d9676a4979c7d08f18cbb84559426168c769a5b08e61539e2421409a559563bd7dc4fba94da92f57ad347840d557398e75da9c1b3c5f31c9fa899024b66e
|
7
|
+
data.tar.gz: 322436eea5226b598a8988776c80e68886c429c5d021e2136ca45c6521eaaad235bda9d13259d611719172368ab77c8484e815391ffa8926400c1e5d3c869cd2
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
sudo: false
|
2
|
+
services:
|
3
|
+
- redis-server
|
2
4
|
language: ruby
|
3
5
|
# Broken bundler on travis CI - https://github.com/bundler/bundler/issues/2784
|
4
6
|
before_install:
|
@@ -15,17 +17,79 @@ rvm:
|
|
15
17
|
- jruby-19mode
|
16
18
|
- jruby-head
|
17
19
|
- rbx
|
20
|
+
jdk:
|
21
|
+
- openjdk6
|
22
|
+
- openjdk7
|
23
|
+
- oraclejdk7
|
24
|
+
- oraclejdk8
|
18
25
|
env:
|
19
26
|
- SKIP_DUMMY_ROLLBAR=true
|
20
27
|
- SKIP_DUMMY_ROLLBAR=false
|
28
|
+
gemfile:
|
29
|
+
- gemfiles/rails30.gemfile
|
30
|
+
- gemfiles/rails31.gemfile
|
31
|
+
- gemfiles/rails32.gemfile
|
32
|
+
- gemfiles/rails40.gemfile
|
33
|
+
- gemfiles/rails41.gemfile
|
21
34
|
matrix:
|
22
35
|
allow_failures:
|
23
36
|
- rvm: ruby-head
|
24
37
|
- rvm: jruby-18mode
|
25
|
-
- rvm: jruby-19mode
|
26
38
|
- rvm: jruby-head
|
27
|
-
|
39
|
+
|
40
|
+
# NOTE: Allowing this to fail because of some strange error in rspec-core `undefined method `example_group_finished'`.
|
41
|
+
# Seems to work with oraclejdk7.
|
42
|
+
- rvm: jruby-19mode
|
43
|
+
jdk: openjdk7
|
44
|
+
env: SKIP_DUMMY_ROLLBAR=false
|
45
|
+
|
28
46
|
exclude:
|
47
|
+
# Don't run tests for non-jruby environments with the JDK.
|
48
|
+
# NOTE: openjdk7 is missing from these exclusions so that Travis will run at least 1 build for the given rvm.
|
49
|
+
- rvm: 1.8.7
|
50
|
+
jdk: openjdk6
|
51
|
+
- rvm: 1.8.7
|
52
|
+
jdk: oraclejdk7
|
53
|
+
- rvm: 1.8.7
|
54
|
+
jdk: oraclejdk8
|
55
|
+
- rvm: 1.9.2
|
56
|
+
jdk: openjdk6
|
57
|
+
- rvm: 1.9.2
|
58
|
+
jdk: oraclejdk7
|
59
|
+
- rvm: 1.9.2
|
60
|
+
jdk: oraclejdk8
|
61
|
+
- rvm: 1.9.3
|
62
|
+
jdk: openjdk6
|
63
|
+
- rvm: 1.9.3
|
64
|
+
jdk: oraclejdk7
|
65
|
+
- rvm: 1.9.3
|
66
|
+
jdk: oraclejdk8
|
67
|
+
- rvm: 2.0.0
|
68
|
+
jdk: openjdk6
|
69
|
+
- rvm: 2.0.0
|
70
|
+
jdk: oraclejdk7
|
71
|
+
- rvm: 2.0.0
|
72
|
+
jdk: oraclejdk8
|
73
|
+
- rvm: 2.1.0
|
74
|
+
jdk: openjdk6
|
75
|
+
- rvm: 2.1.0
|
76
|
+
jdk: oraclejdk7
|
77
|
+
- rvm: 2.1.0
|
78
|
+
jdk: oraclejdk8
|
79
|
+
- rvm: ruby-head
|
80
|
+
jdk: openjdk6
|
81
|
+
- rvm: ruby-head
|
82
|
+
jdk: oraclejdk7
|
83
|
+
- rvm: ruby-head
|
84
|
+
jdk: oraclejdk8
|
85
|
+
- rvm: rbx
|
86
|
+
jdk: openjdk6
|
87
|
+
- rvm: rbx
|
88
|
+
jdk: oraclejdk7
|
89
|
+
- rvm: rbx
|
90
|
+
jdk: oraclejdk8
|
91
|
+
|
92
|
+
# TODO: comment as to why these are excluded
|
29
93
|
- rvm: 1.8.7
|
30
94
|
gemfile: gemfiles/rails40.gemfile
|
31
95
|
- rvm: 1.8.7
|
@@ -84,9 +148,3 @@ matrix:
|
|
84
148
|
gemfile: gemfiles/rails40.gemfile
|
85
149
|
- rvm: rbx
|
86
150
|
gemfile: gemfiles/rails41.gemfile
|
87
|
-
gemfile:
|
88
|
-
- gemfiles/rails30.gemfile
|
89
|
-
- gemfiles/rails31.gemfile
|
90
|
-
- gemfiles/rails32.gemfile
|
91
|
-
- gemfiles/rails40.gemfile
|
92
|
-
- gemfiles/rails41.gemfile
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,26 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 2.0.0
|
4
|
+
|
5
|
+
Possibly breaking changes:
|
6
|
+
|
7
|
+
- If active_support version < 4.1.0 is installed, this gem will now monkeypatch `BasicSocket#to_json`. This is needed to work around a bug causing JSON serialization to fail when the payload contains a Socket instance. We don't expect this to break anything for anyone, unless you are using active_support version < 4.1.0 and also happened to be relying on the buggy Socket serialization behavior.
|
8
|
+
|
9
|
+
Bug fixes:
|
10
|
+
|
11
|
+
- Use the JSON gem or native by default. Along with the aforementioned monkeypatch, this fixes the existing bug in active_support < 4.1.0 serializing Socket instances. To disable the monkeypatch, set `config.disable_core_monkey_patch = true`.
|
12
|
+
- Add Encoding module, with Encoder and LegacyEncoder classes. This fixes some issues with ISO-8859 strings
|
13
|
+
|
14
|
+
Other changes:
|
15
|
+
|
16
|
+
- Update README.md and warn about upgrade to capistrano >= 3.1
|
17
|
+
- Fix error in code example for custom Async handlers
|
18
|
+
|
3
19
|
## 1.5.3
|
4
20
|
|
5
21
|
Bug fixes:
|
6
22
|
|
7
|
-
- Run `rollbar-rails-runner` in the context of `Rails` module so we avoid namespace
|
23
|
+
- Run `rollbar-rails-runner` in the context of `Rails` module so we avoid namespace conflicts. See [#242](https://github.com/rollbar/rollbar-gem/pull/242)
|
8
24
|
|
9
25
|
## 1.5.2
|
10
26
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Rollbar notifier for Ruby [![Build Status](https://api.travis-ci.org/rollbar/rollbar-gem.svg?branch=
|
1
|
+
# Rollbar notifier for Ruby [![Build Status](https://api.travis-ci.org/rollbar/rollbar-gem.svg?branch=v2.0.0)](https://travis-ci.org/rollbar/rollbar-gem/branches)
|
2
2
|
|
3
3
|
<!-- RemoveNext -->
|
4
4
|
[Rollbar](https://rollbar.com) is an error tracking service for Ruby and other languages. The Rollbar service will alert you of problems with your code and help you understand them in a ways never possible before. We love it and we hope you will too.
|
@@ -12,7 +12,7 @@ This is the Ruby library for Rollbar. It will instrument many kinds of Ruby appl
|
|
12
12
|
Add this line to your application's Gemfile:
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
gem 'rollbar', '~>
|
15
|
+
gem 'rollbar', '~> 2.0.0
|
16
16
|
```
|
17
17
|
|
18
18
|
And then execute:
|
@@ -121,13 +121,13 @@ begin
|
|
121
121
|
rescue NoMethodError => e
|
122
122
|
# simple exception report (level can be 'debug', 'info', 'warning', 'error' and 'critical')
|
123
123
|
Rollbar.log('error', e)
|
124
|
-
|
124
|
+
|
125
125
|
# same functionality as above
|
126
126
|
Rollbar.error(e)
|
127
|
-
|
127
|
+
|
128
128
|
# with a description
|
129
129
|
Rollbar.error(e, 'The user info hash doesn\'t contain the correct data')
|
130
|
-
|
130
|
+
|
131
131
|
# with extra data giving more insight about the exception
|
132
132
|
Rollbar.error(e, :user_info => user_info, :job_id => job_id)
|
133
133
|
end
|
@@ -154,7 +154,7 @@ after_validation :report_validation_errors_to_rollbar
|
|
154
154
|
|
155
155
|
### Advanced usage
|
156
156
|
|
157
|
-
You can use `Rollbar.scope()` to copy a notifier instance and customize the payload data for one-off reporting. The hash argument to `scope()` will be merged into the copied notifier's "payload options", a hash that will be merged into the final payload just before it is reported to Rollbar.
|
157
|
+
You can use `Rollbar.scope()` to copy a notifier instance and customize the payload data for one-off reporting. The hash argument to `scope()` will be merged into the copied notifier's "payload options", a hash that will be merged into the final payload just before it is reported to Rollbar.
|
158
158
|
|
159
159
|
For example:
|
160
160
|
|
@@ -504,7 +504,7 @@ config.use_thread
|
|
504
504
|
You can supply your own handler using ```config.async_handler```. The object to set for `async_handler` should respond to `#call` and receive the payload. The handler should schedule the payload for later processing (i.e. with a delayed_job, in a resque queue, etc.) and should itself return immediately. For example:
|
505
505
|
|
506
506
|
```ruby
|
507
|
-
config.use_async
|
507
|
+
config.use_async = true
|
508
508
|
config.async_handler = Proc.new { |payload|
|
509
509
|
Thread.new { Rollbar.process_payload_safely(payload) }
|
510
510
|
}
|
@@ -590,6 +590,8 @@ set :rollbar_env, Proc.new { fetch :stage }
|
|
590
590
|
set :rollbar_role, Proc.new { :app }
|
591
591
|
```
|
592
592
|
|
593
|
+
NOTE: We've seen problems with Capistrano version `3.0.x` where the revision reported is incorrect. Version `3.1.0` and higher works correctly.
|
594
|
+
|
593
595
|
### Capistrano 2
|
594
596
|
|
595
597
|
Add the following to ```deploy.rb```:
|
@@ -665,6 +667,14 @@ require 'json'
|
|
665
667
|
MultiJson.use(:json_common)
|
666
668
|
```
|
667
669
|
|
670
|
+
If you are using jRuby with Oracle and JDK7, you may be expecting some errors sending reports to our API. This is caused by a bug in that JDK and the primer number used in the SSL algorithm. In order to fix this you can set the next configuration:
|
671
|
+
|
672
|
+
```ruby
|
673
|
+
Rollbar.configure do|config|
|
674
|
+
config.endpoint = 'https://api-alt.rollbar.com/api/1/item/'
|
675
|
+
end
|
676
|
+
```
|
677
|
+
|
668
678
|
|
669
679
|
## Help / Support
|
670
680
|
|
@@ -2,21 +2,22 @@ require 'rollbar/rails'
|
|
2
2
|
Rollbar.configure do |config|
|
3
3
|
# Without configuration, Rollbar is enabled in all environments.
|
4
4
|
# To disable in specific environments, set config.enabled=false.
|
5
|
-
|
5
|
+
|
6
|
+
<%- if (defined? EY::Config) -%>
|
6
7
|
# Here we'll disable in 'test' and 'development':
|
7
8
|
if Rails.env.test? or Rails.env.development?
|
8
9
|
config.enabled = false
|
9
10
|
else
|
10
11
|
config.access_token = EY::Config.get('rollbar', 'ROLLBAR_ACCESS_TOKEN')
|
11
12
|
end
|
12
|
-
|
13
|
+
<%- else -%>
|
13
14
|
config.access_token = <%= access_token_expr %>
|
14
15
|
|
15
16
|
# Here we'll disable in 'test':
|
16
17
|
if Rails.env.test?
|
17
18
|
config.enabled = false
|
18
19
|
end
|
19
|
-
|
20
|
+
<%- end -%>
|
20
21
|
|
21
22
|
# By default, Rollbar will try to call the `current_user` controller method
|
22
23
|
# to fetch the logged-in user object, and then call that object's `id`,
|
data/lib/rollbar.rb
CHANGED
@@ -2,7 +2,6 @@ require 'net/https'
|
|
2
2
|
require 'socket'
|
3
3
|
require 'thread'
|
4
4
|
require 'uri'
|
5
|
-
require 'multi_json'
|
6
5
|
require 'forwardable'
|
7
6
|
|
8
7
|
begin
|
@@ -11,7 +10,9 @@ rescue LoadError
|
|
11
10
|
end
|
12
11
|
|
13
12
|
require 'rollbar/version'
|
13
|
+
require 'rollbar/json'
|
14
14
|
require 'rollbar/configuration'
|
15
|
+
require 'rollbar/encoding'
|
15
16
|
require 'rollbar/logger_proxy'
|
16
17
|
require 'rollbar/exception_reporter'
|
17
18
|
require 'rollbar/util'
|
@@ -20,10 +21,6 @@ require 'rollbar/delay/girl_friday'
|
|
20
21
|
require 'rollbar/delay/thread'
|
21
22
|
require 'rollbar/truncation'
|
22
23
|
|
23
|
-
unless ''.respond_to? :encode
|
24
|
-
require 'iconv'
|
25
|
-
end
|
26
|
-
|
27
24
|
module Rollbar
|
28
25
|
ATTACHMENT_CLASSES = %w[
|
29
26
|
ActionDispatch::Http::UploadedFile
|
@@ -444,28 +441,7 @@ module Rollbar
|
|
444
441
|
end
|
445
442
|
|
446
443
|
def enforce_valid_utf8(payload)
|
447
|
-
normalizer = lambda
|
448
|
-
is_symbol = object.is_a?(Symbol)
|
449
|
-
|
450
|
-
return object unless object == object.to_s || is_symbol
|
451
|
-
|
452
|
-
value = object.to_s
|
453
|
-
|
454
|
-
if value.respond_to? :encode
|
455
|
-
options = { :invalid => :replace, :undef => :replace, :replace => '' }
|
456
|
-
ascii_encodings = [Encoding.find('US-ASCII'), Encoding.find('ASCII-8BIT')]
|
457
|
-
|
458
|
-
args = ['UTF-8']
|
459
|
-
args << 'binary' if ascii_encodings.include?(value.encoding)
|
460
|
-
args << options
|
461
|
-
|
462
|
-
encoded_value = value.encode(*args)
|
463
|
-
else
|
464
|
-
encoded_value = ::Iconv.conv('UTF-8//IGNORE', 'UTF-8', value)
|
465
|
-
end
|
466
|
-
|
467
|
-
is_symbol ? encoded_value.to_sym : encoded_value
|
468
|
-
end
|
444
|
+
normalizer = lambda { |object| Encoding.encode(object) }
|
469
445
|
|
470
446
|
Rollbar::Util.iterate_and_update(payload, normalizer)
|
471
447
|
end
|
@@ -508,7 +484,7 @@ module Rollbar
|
|
508
484
|
|
509
485
|
def send_payload(payload)
|
510
486
|
log_info '[Rollbar] Sending payload'
|
511
|
-
payload =
|
487
|
+
payload = Rollbar::JSON.load(payload) if payload.is_a?(String)
|
512
488
|
|
513
489
|
if configuration.use_eventmachine
|
514
490
|
send_payload_using_eventmachine(payload)
|
@@ -648,7 +624,7 @@ module Rollbar
|
|
648
624
|
rescue
|
649
625
|
next unless handler == failover_handlers.last
|
650
626
|
|
651
|
-
log_error "[Rollbar] All failover handlers failed while processing payload: #{
|
627
|
+
log_error "[Rollbar] All failover handlers failed while processing payload: #{Rollbar::JSON.dump(payload)}"
|
652
628
|
end
|
653
629
|
end
|
654
630
|
end
|
@@ -660,10 +636,10 @@ module Rollbar
|
|
660
636
|
result = Truncation.truncate(stringified_payload)
|
661
637
|
return result unless Truncation.truncate?(result)
|
662
638
|
|
663
|
-
original_size =
|
639
|
+
original_size = Rollbar::JSON.dump(payload).bytesize
|
664
640
|
final_size = result.bytesize
|
665
641
|
send_failsafe("Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}", nil)
|
666
|
-
log_error "[Rollbar] Payload too large to be sent: #{
|
642
|
+
log_error "[Rollbar] Payload too large to be sent: #{Rollbar::JSON.dump(payload)}"
|
667
643
|
|
668
644
|
nil
|
669
645
|
end
|
@@ -710,14 +686,17 @@ module Rollbar
|
|
710
686
|
|
711
687
|
yield(configuration)
|
712
688
|
|
689
|
+
configure_json_backend
|
713
690
|
require_hooks
|
714
|
-
|
715
|
-
# to use Rollbar.scoped
|
716
|
-
require 'rollbar/core_ext/thread'
|
691
|
+
require_core_extensions
|
717
692
|
|
718
693
|
reset_notifier!
|
719
694
|
end
|
720
695
|
|
696
|
+
def configure_json_backend
|
697
|
+
Rollbar::JSON.setup
|
698
|
+
end
|
699
|
+
|
721
700
|
def reconfigure
|
722
701
|
@configuration = Configuration.new
|
723
702
|
@configuration.enabled = true
|
@@ -750,6 +729,28 @@ module Rollbar
|
|
750
729
|
require 'rollbar/better_errors' if defined?(BetterErrors)
|
751
730
|
end
|
752
731
|
|
732
|
+
def require_core_extensions
|
733
|
+
# This monkey patch is always needed in order
|
734
|
+
# to use Rollbar.scoped
|
735
|
+
require 'rollbar/core_ext/thread'
|
736
|
+
|
737
|
+
return if configuration.disable_core_monkey_patch
|
738
|
+
|
739
|
+
# Needed to avoid active_support (< 4.1.0) bug serializing JSONs
|
740
|
+
require 'rollbar/core_ext/basic_socket' if monkey_patch_socket?
|
741
|
+
end
|
742
|
+
|
743
|
+
def monkey_patch_socket?
|
744
|
+
return false unless defined?(ActiveSupport::VERSION::STRING)
|
745
|
+
|
746
|
+
major, minor = ActiveSupport::VERSION::STRING.split('.').map(&:to_i)
|
747
|
+
|
748
|
+
return true if major == 3
|
749
|
+
return true if major == 4 && minor == 0
|
750
|
+
|
751
|
+
false
|
752
|
+
end
|
753
|
+
|
753
754
|
def wrap_delayed_worker
|
754
755
|
return unless defined?(Delayed) && defined?(Delayed::Worker) && configuration.delayed_job_enabled
|
755
756
|
|
@@ -11,6 +11,7 @@ module Rollbar
|
|
11
11
|
attr_accessor :delayed_job_enabled
|
12
12
|
attr_accessor :default_logger
|
13
13
|
attr_accessor :disable_monkey_patch
|
14
|
+
attr_accessor :disable_core_monkey_patch
|
14
15
|
attr_accessor :dj_threshold
|
15
16
|
attr_accessor :enabled
|
16
17
|
attr_accessor :endpoint
|
@@ -53,6 +54,7 @@ module Rollbar
|
|
53
54
|
@default_logger = lambda { Logger.new(STDERR) }
|
54
55
|
@delayed_job_enabled = true
|
55
56
|
@disable_monkey_patch = false
|
57
|
+
@disable_core_monkey_patch = false
|
56
58
|
@dj_threshold = 0
|
57
59
|
@enabled = nil # set to true when configure is called
|
58
60
|
@endpoint = DEFAULT_ENDPOINT
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rollbar
|
2
|
+
module Encoding
|
3
|
+
def self.encode(object)
|
4
|
+
can_be_encoded = object.is_a?(Symbol) || object.is_a?(String)
|
5
|
+
|
6
|
+
return object unless can_be_encoded
|
7
|
+
|
8
|
+
encoding_class.new(object).encode
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.encoding_class
|
12
|
+
if String.instance_methods.include?(:encode)
|
13
|
+
require 'rollbar/encoding/encoder'
|
14
|
+
Encoder
|
15
|
+
else
|
16
|
+
require 'rollbar/encoding/legacy_encoder'
|
17
|
+
LegacyEncoder
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Rollbar
|
2
|
+
module Encoding
|
3
|
+
class Encoder
|
4
|
+
ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII]
|
5
|
+
ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1]
|
6
|
+
ENCODING_OPTIONS = { :invalid => :replace, :undef => :replace, :replace => '' }
|
7
|
+
|
8
|
+
attr_accessor :object
|
9
|
+
|
10
|
+
def initialize(object)
|
11
|
+
@object = object
|
12
|
+
end
|
13
|
+
|
14
|
+
def encode
|
15
|
+
value = object.to_s
|
16
|
+
|
17
|
+
encoded_value = force_encoding(value).encode(*encoding_args(value))
|
18
|
+
|
19
|
+
object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def force_encoding(value)
|
25
|
+
return value if value.frozen?
|
26
|
+
|
27
|
+
value.force_encoding(detect_encoding(value)) if value.encoding == ::Encoding::UTF_8
|
28
|
+
|
29
|
+
value
|
30
|
+
end
|
31
|
+
|
32
|
+
def detect_encoding(v)
|
33
|
+
value = v.dup
|
34
|
+
|
35
|
+
ALL_ENCODINGS.detect do |encoding|
|
36
|
+
begin
|
37
|
+
value.force_encoding(encoding).encode(::Encoding::UTF_8).codepoints
|
38
|
+
true
|
39
|
+
rescue
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def encoding_args(value)
|
46
|
+
args = ['UTF-8']
|
47
|
+
args << 'binary' if ASCII_ENCODINGS.include?(value.encoding)
|
48
|
+
args << ENCODING_OPTIONS
|
49
|
+
|
50
|
+
args
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|