class Dockerspec::DockerExceptionParser
A class to parse `Docker::Error` exceptions.
Public Class Methods
Parses Docker exceptions.
Raises the same exception if the format is unknown.
@example
rescue ::Docker::Error::DockerError => e DockerExceptionParser.new(e) end
@param e [Exception] The exception object to parse.
@raise [Dockerspec::DockerError] When the exception format is known. @raise [Exception] When the exception format is unknown.
@api public
# File lib/dockerspec/docker_exception_parser.rb, line 45 def initialize(e) e_ary = parse_exception(e) raise_docker_error_exception(e_ary) raise e end
Protected Instance Methods
Generates a formated error message.
@param error [String] The error message. @param output [String] The generated stdout output.
@return [String] The resulting error message.
@api private
# File lib/dockerspec/docker_exception_parser.rb, line 130 def generate_error_message(error, output) [ "#{error}\n", "OUTPUT: \n#{output.gsub(/^/, ' ' * 8)}", "ERROR: #{error}\n\n" ].join("\n") end
Gets the error message from the errorDetail field.
@param e_ary [Array<Hash>] The list of JSON messages already parsed.
@return [String] The error message string.
@api private
# File lib/dockerspec/docker_exception_parser.rb, line 100 def parse_error_detail(e_ary) e_detail = e_ary.select { |x| x.is_a?(Hash) && x.key?('errorDetail') }[0] return nil unless e_detail.is_a?(Hash) return e_detail['message'] if e_detail.key?('message') return e_detail['error'] if e_detail.key?('error') end
Parses the exception JSON message.
The message must be a list of JSON messages merged by a new line.
A valid exception message example:
“` {“stream”:“Step 1 : FROM alpine:3.2n”} {“stream”:“ —u003e d6ead20d5571n”} {“stream”:“Step 2 : RUN apk add –update wrong-package-namen”} {“stream”:“ —u003e Running in 290a46fa8bf4n”} {“stream”:“fetch dl-4.alpinelinux.org/alpine/v3.2/main/…n”} {“stream”:“ERROR: unsatisfiable constraints:n”} {“stream”:“ wrong-package-name (missing):n required by: world…n”} {“errorDetail”:{“message”:“The command …”},“error”:“The command …”} “`
@example
self.parse_exception(e) #=> [{ "stream" => "Step 1 : FROM alpine:3.2\n" }, "errorDetail" => ...
@param e [Exception] The exception object to parse.
@return [Array<Hash>] The list of JSON messages parsed.
@return
@api private
# File lib/dockerspec/docker_exception_parser.rb, line 83 def parse_exception(e) msg = e.to_s json = msg.to_s.sub(/^Couldn't find id: /, '').split("\n").map(&:chomp) json.map { |str| JSON.parse(str) } rescue JSON::ParserError raise e end
Gets all the console output from the stream logs.
@param e_ary [Array<Hash>] The list of JSON messages already parsed.
@return [String] The generated stdout output.
@api private
# File lib/dockerspec/docker_exception_parser.rb, line 116 def parse_streams(e_ary) e_ary.map { |x| x.is_a?(Hash) && x['stream'] }.compact.join end
Raises the right {Dockerspec::DockerError} exception.
Nothing is raised if the exception format is unknown.
@param e_ary [Array<Hash>] The list of JSON messages already parsed.
@return void
@raise [Dockerspec::DockerError] When the exception format is known.
@api private
# File lib/dockerspec/docker_exception_parser.rb, line 151 def raise_docker_error_exception(e_ary) e_ary.select { |x| x.is_a?(Hash) && x.key?('errorDetail') }[0] output = parse_streams(e_ary) error_msg = parse_error_detail(e_ary) return if error_msg.nil? raise DockerError, generate_error_message(error_msg, output) end