forked from hashicorp/vagrant
/
errors.rb
342 lines (282 loc) · 9.65 KB
/
errors.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# This file contains all of the internal errors in Vagrant's core
# commands, actions, etc.
module Vagrant
# This module contains all of the internal errors in Vagrant's core.
# These errors are _expected_ errors and as such don't typically represent
# bugs in Vagrant itself. These are meant as a way to detect errors and
# display them in a user-friendly way.
#
# # Defining a new Error
#
# To define a new error, inherit from {VagrantError}, which lets Vagrant
# know that this is an expected error, and also gives you some helpers for
# providing exit codes and error messages. An example is shown below, then
# it is explained:
#
# class MyError < Vagrant::Errors::VagrantError
# error_key "my_error"
# end
#
# This creates an error with an I18n error key of "my_error." {VagrantError}
# uses I18n to look up error messages, in the "vagrant.errors" namespace. So
# in the above, the error message would be the translation of "vagrant.errors.my_error"
#
# If you don't want to use I18n, you can override the {#initialize} method and
# set your own error message.
#
# # Raising an Error
#
# To raise an error, it is nothing special, just raise it like any normal
# exception:
#
# raise MyError.new
#
# Eventually this exception will bubble out to the `vagrant` binary which
# will show a nice error message. And if it is raised in the middle of a
# middleware sequence, then {Action::Warden} will catch it and begin the
# recovery process prior to exiting.
module Errors
# Main superclass of any errors in Vagrant. This provides some
# convenience methods for setting the status code and error key.
# The status code is used by the `vagrant` executable as the
# error code, and the error key is used as a default message from
# I18n.
class VagrantError < StandardError
@@used_codes = []
def self.status_code(code = nil)
if code
raise "Status code already in use: #{code}" if @@used_codes.include?(code)
@@used_codes << code
end
define_method(:status_code) { code }
end
def self.error_key(key=nil, namespace=nil)
define_method(:error_key) { key }
error_namespace(namespace) if namespace
end
def self.error_namespace(namespace)
define_method(:error_namespace) { namespace }
end
def initialize(message=nil, *args)
message = { :_key => message } if message && !message.is_a?(Hash)
message = { :_key => error_key, :_namespace => error_namespace }.merge(message || {})
message = translate_error(message)
super
end
# The default error namespace which is used for the error key.
# This can be overridden here or by calling the "error_namespace"
# class method.
def error_namespace; "vagrant.errors"; end
# The key for the error message. This should be set using the
# {error_key} method but can be overridden here if needed.
def error_key; nil; end
protected
def translate_error(opts)
return nil if !opts[:_key]
I18n.t("#{opts[:_namespace]}.#{opts[:_key]}", opts)
end
end
class BaseVMNotFound < VagrantError
status_code(18)
error_key(:base_vm_not_found)
end
class BoxAlreadyExists < VagrantError
status_code(14)
error_key(:already_exists, "vagrant.actions.box.unpackage")
end
class BoxDownloadUnknownType < VagrantError
status_code(13)
error_key(:unknown_type, "vagrant.actions.box.download")
end
class BoxNotFound < VagrantError
status_code(2)
error_key(:box_not_found)
end
class BoxNotSpecified < VagrantError
status_code(22)
error_key(:not_specified, "vagrant.actions.vm.check_box")
end
class BoxSpecifiedDoesntExist < VagrantError
status_code(23)
error_key(:does_not_exist, "vagrant.actions.vm.check_box")
end
class BoxVerificationFailed < VagrantError
status_code(15)
error_key(:failed, "vagrant.actions.box.verify")
end
class CLIMissingEnvironment < VagrantError
status_code(1)
error_key(:cli_missing_env)
end
class ConfigValidationFailed < VagrantError
status_code(42)
error_key(:config_validation)
end
class DotfileIsDirectory < VagrantError
status_code(46)
error_key(:dotfile_is_directory)
end
class DownloaderFileDoesntExist < VagrantError
status_code(37)
error_key(:file_missing, "vagrant.downloaders.file")
end
class DownloaderHTTPSocketError < VagrantError
status_code(38)
error_key(:socket_error, "vagrant.downloaders.http")
end
class DownloaderHTTPStatusError < VagrantError
status_code(51)
error_key(:status_error, "vagrant.downloaders.http")
end
class EnvironmentLockedError < VagrantError
status_code(52)
error_key(:environment_locked)
end
class ForwardPortAutolistEmpty < VagrantError
status_code(27)
error_key(:auto_empty, "vagrant.actions.vm.forward_ports")
end
class ForwardPortBelowThreshold < VagrantError
status_code(25)
error_key(:below_threshold_error, "vagrant.actions.vm.forward_ports")
end
class ForwardPortCollision < VagrantError
status_code(26)
error_key(:collision_error, "vagrant.actions.vm.forward_ports")
end
class MultiVMEnvironmentRequired < VagrantError
status_code(5)
error_key(:multi_vm_required)
end
class MultiVMTargetRequired < VagrantError
status_code(7)
error_key(:multi_vm_target_required)
end
class NetworkCollision < VagrantError
status_code(29)
error_key(:collides, "vagrant.actions.vm.network")
end
class NetworkNotFound < VagrantError
status_code(30)
error_key(:not_found, "vagrant.actions.vm.network")
end
# Note: This is a temporary error for Windows users while host-only
# networking doesn't quite work.
class NetworkNotImplemented < VagrantError
status_code(49)
error_key(:windows_not_implemented, "vagrant.actions.vm.network")
end
class NFSHostRequired < VagrantError
status_code(31)
error_key(:host_required, "vagrant.actions.vm.nfs")
end
class NFSNotSupported < VagrantError
status_code(32)
error_key(:not_supported, "vagrant.actions.vm.nfs")
end
class NFSNoHostNetwork < VagrantError
status_code(33)
error_key(:no_host_network, "vagrant.actions.vm.nfs")
end
class NoEnvironmentError < VagrantError
status_code(3)
error_key(:no_env)
end
class PackageIncludeMissing < VagrantError
status_code(20)
error_key(:include_file_missing, "vagrant.actions.general.package")
end
class PackageOutputExists < VagrantError
status_code(16)
error_key(:output_exists, "vagrant.actions.general.package")
end
class PackageRequiresDirectory < VagrantError
status_code(19)
error_key(:requires_directory, "vagrant.actions.general.package")
end
class PersistDotfileExists < VagrantError
status_code(34)
error_key(:dotfile_error, "vagrant.actions.vm.persist")
end
class SSHAuthenticationFailed < VagrantError
status_code(11)
error_key(:ssh_authentication_failed)
end
class SSHConnectionRefused < VagrantError
status_code(43)
error_key(:ssh_connection_refused)
end
class SSHKeyBadPermissions < VagrantError
status_code(12)
error_key(:ssh_key_bad_permissions)
end
class SSHPortNotDetected < VagrantError
status_code(50)
error_key(:ssh_port_not_detected)
end
class SSHUnavailable < VagrantError
status_code(45)
error_key(:ssh_unavailable)
end
class SSHUnavailableWindows < VagrantError
status_code(10)
error_key(:ssh_unavailable_windows)
end
class VagrantInterrupt < VagrantError
status_code(40)
error_key(:interrupted)
end
class VagrantfileSyntaxError < VagrantError
status_code(41)
error_key(:vagrantfile_syntax_error)
end
class VirtualBoxInvalidVersion < VagrantError
status_code(17)
error_key(:virtualbox_invalid_version)
end
class VirtualBoxNotDetected < VagrantError
status_code(8)
error_key(:virtualbox_not_detected)
end
# Note that this is a subclass of VirtualBoxNotDetected, so developers
# who script Vagrant or use it as a library in any way can rescue from
# "VirtualBoxNotDetected" and catch both errors, which represent the
# same thing. This subclass simply has a specialized error message.
class VirtualBoxNotDetected_Win64 < VirtualBoxNotDetected
status_code(48)
error_key(:virtualbox_not_detected_win64)
end
class VMBaseMacNotSpecified < VagrantError
status_code(47)
error_key(:no_base_mac, "vagrant.actions.vm.match_mac")
end
class VMFailedToBoot < VagrantError
status_code(21)
error_key(:failed_to_boot, "vagrant.actions.vm.boot")
end
class VMImportFailure < VagrantError
status_code(28)
error_key(:failure, "vagrant.actions.vm.import")
end
class VMNotCreatedError < VagrantError
status_code(6)
error_key(:vm_creation_required)
end
class VMNotFoundError < VagrantError
status_code(4)
error_key(:vm_not_found)
end
class VMNotRunningError < VagrantError
status_code(44)
error_key(:vm_not_running)
end
class VMPowerOffToPackage < VagrantError
status_code(24)
error_key(:power_off, "vagrant.actions.vm.export")
end
class VMSystemError < VagrantError
status_code(39)
error_namespace("vagrant.errors.system")
end
end
end