Skip to content

Commit d8fa43b

Browse files
committedFeb 12, 2016
Improve error output on extract_messages failure
The `extract_messages` helper was designed to fail loudly if the input didn't match what was expected by the regex. The goal was to help hook authors debug and catch these issues quickly and easily. However, there are some situations where hook authors did nothing wrong, for example if you are using `rbenv` and on a version of Ruby where a gem hasn't yet been installed (but the shim already exists), you'll get an error like the following: The `rubocop' command exists in these Ruby versions: 1.9.3-p551 2.1.1 2.1.2 2.2.1 2.2.2 2.3.0 jruby-1.7.20 ...which appears like the following in the hook error output: Analyzing with RuboCop..............................[RuboCop] FAILED Hook raised unexpected error Unexpected output: unable to determine line number or type of error/warning for message '' lib/overcommit/hook/pre_commit/base.rb:31:in `block in extract_messages' lib/overcommit/hook/pre_commit/base.rb:28:in `map' lib/overcommit/hook/pre_commit/base.rb:28:in `extract_messages' lib/overcommit/hook/pre_commit/rubo_cop.rb:19:in `run' lib/overcommit/hook/base.rb:45:in `block in run_and_transform' lib/overcommit/utils.rb:259:in `with_environment' lib/overcommit/hook/base.rb:45:in `run_and_transform' lib/overcommit/hook_runner.rb:152:in `run_hook' lib/overcommit/hook_runner.rb:88:in `block in consume' lib/overcommit/hook_runner.rb:85:in `loop' lib/overcommit/hook_runner.rb:85:in `consume' The stacktrace in this case is unsightly and doesn't explain what's actually going on. Fix this by throwing a special class of error and printing the remaining unprocessed output. Fixes sds#335
1 parent 53761f7 commit d8fa43b

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
Unicode characters could cause a crash due to invalid byte sequences
77
* Add `ForbiddenBranches` pre-commit hook which prevents creating a commit
88
on any blacklisted branch by name/pattern
9+
* Improve error message output when there is a problem processing messages
10+
via `extract_messages` pre-commit hook helper
911

1012
## 0.32.0.rc1
1113

‎lib/overcommit/exceptions.rb

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class InvalidHookDefinition < StandardError; end
4242
# Raised when one or more hook plugin signatures have changed.
4343
class InvalidHookSignature < StandardError; end
4444

45+
# Raised when there is a problem processing output into {Hook::Messages}s.
46+
class MessageProcessingError < StandardError; end
47+
4548
# Raised when an installation target already contains non-Overcommit hooks.
4649
class PreExistingHooks < StandardError; end
4750
end

‎lib/overcommit/hook/pre_commit/base.rb

+13-7
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@ class Base < Overcommit::Hook::Base
2222
# @param type_categorizer [Proc] function executed against the `type`
2323
# capture group to convert it to a `:warning` or `:error` symbol. Assumes
2424
# `:error` if `nil`.
25-
# @raise [RuntimeError] line of output did not match regex
25+
# @raise [Overcommit::Exceptions::MessageProcessingError] line of output did
26+
# not match regex
2627
# @return [Array<Message>]
2728
def extract_messages(output_messages, regex, type_categorizer = nil)
28-
output_messages.map do |message|
29+
output_messages.map.with_index do |message, index|
2930
unless match = message.match(regex)
30-
raise 'Unexpected output: unable to determine line number or type ' \
31-
"of error/warning for message '#{message}'"
31+
raise Overcommit::Exceptions::MessageProcessingError,
32+
'Unexpected output: unable to determine line number or type ' \
33+
"of error/warning for output:\n" \
34+
"#{output_messages[index..-1].join("\n")}"
3235
end
3336

3437
file = extract_file(match, message)
@@ -43,7 +46,8 @@ def extract_file(match, message)
4346
return unless match.names.include?('file')
4447

4548
if match[:file].to_s.empty?
46-
raise "Unexpected output: no file found in '#{message}'"
49+
raise Overcommit::Exceptions::MessageProcessingError,
50+
"Unexpected output: no file found in '#{message}'"
4751
end
4852

4953
match[:file]
@@ -53,15 +57,17 @@ def extract_line(match, message)
5357
return unless match.names.include?('line')
5458
Integer(match[:line])
5559
rescue ArgumentError, TypeError
56-
raise "Unexpected output: invalid line number found in '#{message}'"
60+
raise Overcommit::Exceptions::MessageProcessingError,
61+
"Unexpected output: invalid line number found in '#{message}'"
5762
end
5863

5964
def extract_type(match, message, type_categorizer)
6065
if type_categorizer
6166
type_match = match.names.include?('type') ? match[:type] : nil
6267
type = type_categorizer.call(type_match)
6368
unless Overcommit::Hook::MESSAGE_TYPES.include?(type)
64-
raise "Invalid message type '#{type}' for '#{message}': must " \
69+
raise Overcommit::Exceptions::MessageProcessingError,
70+
"Invalid message type '#{type}' for '#{message}': must " \
6571
"be one of #{Overcommit::Hook::MESSAGE_TYPES.inspect}"
6672
end
6773
type

‎lib/overcommit/hook_runner.rb

+3
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ def run_hook(hook) # rubocop:disable Metrics/CyclomaticComplexity
150150
return if should_skip?(hook)
151151

152152
status, output = hook.run_and_transform
153+
rescue Overcommit::Exceptions::MessageProcessingError => ex
154+
status = :fail
155+
output = ex.message
153156
rescue => ex
154157
status = :fail
155158
output = "Hook raised unexpected error\n#{ex.message}\n#{ex.backtrace.join("\n")}"

0 commit comments

Comments
 (0)