PageRenderTime 29ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/omnibus/exceptions.rb

https://github.com/opscode/omnibus
Ruby | 354 lines | 269 code | 48 blank | 37 comment | 8 complexity | e0697dc3b2687e3670c1e00277ff1419 MD5 | raw file
  1. #
  2. # Copyright 2014-2018 Chef Software, Inc.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. module Omnibus
  17. class Error < RuntimeError; end
  18. class NoPackageFile < Error
  19. def initialize(path)
  20. @path = path
  21. end
  22. def to_s
  23. <<~EOH
  24. Could not locate or access the package at the given path:
  25. #{@path}
  26. EOH
  27. end
  28. end
  29. class NoPackageMetadataFile < Error
  30. def initialize(path)
  31. @path = path
  32. end
  33. def to_s
  34. <<~EOH
  35. Could not locate or access the package metadata file at the given path:
  36. #{@path}
  37. EOH
  38. end
  39. end
  40. class MissingRequiredAttribute < Error
  41. def initialize(instance, name, sample = "<VALUE>")
  42. @instance, @name, @sample = instance, name, sample
  43. @class = instance.class.name.split("::").last
  44. end
  45. def to_s
  46. <<~EOH
  47. Missing required attribute `#{@name}' for #{@class}. You must
  48. specify a value for `#{@name}' in your DSL file:
  49. #{@name} #{@sample.inspect}
  50. Or set the value on the object:
  51. #{@class.downcase}.#{@name}(#{@sample.inspect})
  52. EOH
  53. end
  54. end
  55. class MissingPatch < Error
  56. def initialize(name, search_paths)
  57. @name, @search_paths = name, search_paths
  58. end
  59. def to_s
  60. <<~EOH
  61. Attempting to apply the patch `#{@name}', but it was not found at any of the
  62. following locations:
  63. #{@search_paths.map { |path| " #{path}" }.join("\n")}
  64. EOH
  65. end
  66. end
  67. class MissingTemplate < Error
  68. def initialize(template, search_paths)
  69. @template, @search_paths = template, search_paths
  70. end
  71. def to_s
  72. <<~EOH
  73. Attempting to evaluate the template `#{@template}', but it was not found at any of
  74. the following locations:
  75. #{@search_paths.map { |path| " #{path}" }.join("\n")}
  76. EOH
  77. end
  78. end
  79. class MissingProject < Error
  80. def initialize(name)
  81. @name = name
  82. @possible_paths = Omnibus.possible_paths_for(Config.project_dir)
  83. end
  84. def to_s
  85. <<~EOH
  86. I could not find a project named `#{@name}' in any of the project locations:"
  87. #{@possible_paths.map { |path| " #{path}" }.join("\n")}
  88. EOH
  89. end
  90. end
  91. class MissingSoftware < Error
  92. def initialize(name)
  93. @name = name
  94. @possible_paths = Omnibus.possible_paths_for(Config.software_dir)
  95. end
  96. def to_s
  97. <<~EOH
  98. I could not find a software named `#{@name}' in any of the software locations:"
  99. #{@possible_paths.map { |path| " #{path}" }.join("\n")}
  100. EOH
  101. end
  102. end
  103. class GemNotInstalled < Error
  104. def initialize(name)
  105. @name = name
  106. end
  107. def to_s
  108. <<~EOH
  109. I could not load the `#{@name}' gem. Please make sure the gem is installed on
  110. your local system by running `gem install #{@name}`, or by adding the following
  111. to your Gemfile:
  112. gem '#{@name}'
  113. EOH
  114. end
  115. end
  116. class InsufficientSpecification < Error
  117. def initialize(key, package)
  118. @key, @package = key, package
  119. end
  120. def to_s
  121. <<~EOH
  122. Software must specify a `#{@key}; to cache it in S3 (#{@package})!
  123. EOH
  124. end
  125. end
  126. class InvalidValue < Error
  127. #
  128. # @param [Symbol] source
  129. # the source method that received an invalid value
  130. # @param [String] message
  131. # the message about why the value is invalid
  132. #
  133. def initialize(source, message)
  134. @source = source
  135. @message = message
  136. end
  137. def to_s
  138. <<~EOH
  139. Invalid value for `#{@source}'. Expected #{@source} to #{@message}!
  140. EOH
  141. end
  142. end
  143. #
  144. # Raised when Omnibus encounters a platform it does not know how to
  145. # build/check/handle.
  146. #
  147. class UnknownPlatform < Error
  148. def initialize(platform)
  149. @platform = platform
  150. end
  151. def to_s
  152. <<~EOH
  153. Unknown platform `#{@platform}'!
  154. I do not know how to proceed!"
  155. EOH
  156. end
  157. end
  158. #
  159. # Raised when Omnibus encounters a platform_version it does not know how to
  160. # build/check/handle.
  161. #
  162. class UnknownPlatformVersion < Error
  163. def initialize(platform, version)
  164. @platform, @version = platform, version
  165. end
  166. def to_s
  167. <<~EOH
  168. Unknown platform version `#{@version}' for #{@platform}!
  169. I do not know how to proceed!"
  170. EOH
  171. end
  172. end
  173. class HealthCheckFailed < Error
  174. def to_s
  175. <<~EOH
  176. The health check failed! Please see above for important information.
  177. EOH
  178. end
  179. end
  180. class ChecksumMissing < Error
  181. def initialize(software)
  182. super <<~EOH
  183. Verification for #{software.name} failed due to a missing checksum.
  184. This added security check is used to prevent MITM attacks when downloading the
  185. remote file. You must specify a checksum for each version of software downloaded
  186. from a remote location.
  187. EOH
  188. end
  189. end
  190. class ChecksumMismatch < Error
  191. def initialize(software, expected, actual)
  192. super <<~EOH
  193. Verification for #{software.name} failed due to a checksum mismatch:
  194. expected: #{expected}
  195. actual: #{actual}
  196. This added security check is used to prevent MITM attacks when downloading the
  197. remote file. If you have updated the version or URL for the download, you will
  198. also need to update the checksum value. You can find the checksum value on the
  199. software publisher's website.
  200. EOH
  201. end
  202. end
  203. class CommandFailed < Error
  204. def initialize(cmd)
  205. status = cmd.exitstatus
  206. if cmd.environment.nil? || cmd.environment.empty?
  207. env = nil
  208. else
  209. env = cmd.environment.sort.map { |k, v| "#{k}=#{v}" }.join(" ")
  210. end
  211. command = cmd.command
  212. command_with_env = [env, command].compact.join(" ")
  213. stdout = cmd.stdout.empty? ? "(nothing)" : cmd.stdout.strip
  214. stderr = cmd.stderr.empty? ? "(nothing)" : cmd.stderr.strip
  215. super <<~EOH
  216. The following shell command exited with status #{status}:
  217. $ #{command_with_env}
  218. Output:
  219. #{stdout}
  220. Error:
  221. #{stderr}
  222. EOH
  223. end
  224. end
  225. class CommandTimeout < Error
  226. def initialize(cmd)
  227. status = cmd.exitstatus
  228. if cmd.environment.nil? || cmd.environment.empty?
  229. env = nil
  230. else
  231. env = cmd.environment.sort.map { |k, v| "#{k}=#{v}" }.join(" ")
  232. end
  233. command = cmd.command
  234. command_with_env = [env, command].compact.join(" ")
  235. timeout = cmd.timeout.to_s.reverse.gsub(/...(?=.)/, '\&,').reverse
  236. super <<~EOH
  237. The following shell command timed out at #{timeout} seconds:
  238. $ #{command_with_env}
  239. Please increase the `:timeout' value or run the command manually to make sure it
  240. is completing successfully. Sometimes it is common for a command to wait for
  241. user input.
  242. EOH
  243. end
  244. end
  245. class ProjectAlreadyDirty < Error
  246. def initialize(project)
  247. name = project.name
  248. culprit = project.culprit.name
  249. super <<~EOH
  250. The project `#{name}' was already marked as dirty by `#{culprit}'. You cannot
  251. mark a project as dirty twice. This is probably a bug in Omnibus and should be
  252. reported.
  253. EOH
  254. end
  255. end
  256. class UnresolvableGitReference < Error
  257. def initialize(ref)
  258. super <<~EOH
  259. Could not resolve `#{ref}' to a valid git SHA-1.
  260. EOH
  261. end
  262. end
  263. class InvalidVersion < Error
  264. def initialize(version)
  265. super <<~EOF
  266. '#{version}' could not be parsed as a valid version.
  267. EOF
  268. end
  269. end
  270. class FailedToSignWindowsPackage < Error
  271. def initialize
  272. super("Failed to sign Windows Package.")
  273. end
  274. end
  275. class LicensingError < Error
  276. def initialize(errors)
  277. @errors = errors
  278. end
  279. def to_s
  280. <<~EOH
  281. Encountered error(s) with project's licensing information.
  282. Failing the build because :fatal_licensing_warnings is set in the configuration.
  283. Error(s):
  284. #{@errors.join("\n ")}
  285. EOH
  286. end
  287. end
  288. end