Skip to content

Instantly share code, notes, and snippets.

@jhubert
Last active February 25, 2017 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhubert/7d75586857d41fb4c45c4491363636e9 to your computer and use it in GitHub Desktop.
Save jhubert/7d75586857d41fb4c45c4491363636e9 to your computer and use it in GitHub Desktop.
Monkey patch the CSV library to add i18n support
require 'csv'
module CoreExtensions
module CSV
module I18n
# Redefine the shift method to catch the exception and attempt to return
# a translated version of the error message using I18n.t
def shift
super
rescue ::CSV::MalformedCSVError => exception
raise $!, translated_exception_message(exception.message), $!.backtrace
end
private
# Parse the exception message and attempt to translate it. If no translation
# is possible, simply return the original error message.
#
# The translation keys need to be defined in your language files as follows.
#
# csv:
# exception:
# field_size_exceeded: "Broken on %{line_number}"
# illegal_quoting:
# missing_or_stray_quote:
# unclosed_quoted_field:
# unquoted_fields_do_not_allow_r_or_n:
#
def translated_exception_message(msg)
return msg unless defined?(I18n)
# This will break if the CSV class changes it's error messages
matches = msg.match(/\s[ion]{2}?\s?\(?line (\d)\)?\.?/i)
return msg if matches.nil?
::I18n.t(
keyify(msg.sub(matches[0], '')),
scope: [:csv, :exception],
line_number: matches[1],
default: msg
)
end
# :reek:UtilityFunction but could use parameterize('_') if rails is present
def keyify(msg)
msg.gsub(/[^a-z]+/i, ' ').strip.gsub(' ', '_').downcase
end
end
end
end
CSV.prepend CoreExtensions::CSV::I18n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment