Skip to content

Commit 29229f4

Browse files
committed
Raise exception when injecting into modules
To me it happened that I accidentally injected my dependencies into a namespace module instead of into a class, like this: module Operations module Articles include Import["repositories.articles"] class Create # ... end end end When I did that, I got a NoMethodError for NilClass somewhere down the line. This led me to believe that I've somehow incorrectly passed parameters to `Import[]`, and it took me a while to realize what was the error. The error occurred because the downstream code assumes the #initialize method will be defined, which is not the case for modules. To improve the developer experience, we detect that we're attempting to inject into a module and raise an explicit exception.
1 parent a501057 commit 29229f4

File tree

5 files changed

+47
-3
lines changed

5 files changed

+47
-3
lines changed

lib/dry/auto_inject.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@ module Dry
4343
def self.AutoInject(container, options = {})
4444
AutoInject::Builder.new(container, options)
4545
end
46+
47+
module AutoInject
48+
class Error < StandardError
49+
end
50+
end
4651
end

lib/dry/auto_inject/dependency_map.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# frozen_string_literal: true
22

3+
require 'dry/auto_inject/errors'
4+
35
module Dry
46
module AutoInject
5-
DuplicateDependencyError = Class.new(StandardError)
6-
DependencyNameInvalid = Class.new(StandardError)
7-
87
VALID_NAME = /([a-z_][a-zA-Z_0-9]*)$/
98

109
class DependencyMap

lib/dry/auto_inject/errors.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
module Dry
4+
module AutoInject
5+
Error = Class.new(StandardError)
6+
DuplicateDependencyError = Class.new(Error)
7+
DependencyNameInvalid = Class.new(Error)
8+
end
9+
end

lib/dry/auto_inject/strategies/constructor.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require 'dry/auto_inject/dependency_map'
4+
require 'dry/auto_inject/errors'
45

56
module Dry
67
module AutoInject
@@ -23,6 +24,8 @@ def initialize(container, *dependency_names)
2324

2425
# @api private
2526
def included(klass)
27+
fail Error, "cannot inject dependencies into a module" unless klass.respond_to?(:new)
28+
2629
define_readers
2730

2831
define_new

spec/dry/auto_inject_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ def initialize(*args)
2828
Class.new(child_class)
2929
end
3030

31+
let(:mod) do
32+
Module.new
33+
end
34+
3135
context 'with positioned args' do
3236
let(:parent_class) do
3337
Class.new do
@@ -167,6 +171,14 @@ def initialize(first, *middle, last)
167171
end
168172
end
169173
end
174+
175+
context 'autoinject in a module' do
176+
it 'raises exception' do
177+
expect {
178+
mod.include Test::AutoInject.args[:one, :two]
179+
}.to raise_error(Dry::AutoInject::Error, /cannot inject/)
180+
end
181+
end
170182
end
171183

172184
context 'with hash arg' do
@@ -312,6 +324,14 @@ def self.included(klass)
312324
end
313325
end
314326
end
327+
328+
context 'autoinject in a module' do
329+
it 'raises exception' do
330+
expect {
331+
mod.include Test::AutoInject.hash[:one, :two]
332+
}.to raise_error(Dry::AutoInject::Error, /cannot inject/)
333+
end
334+
end
315335
end
316336

317337
context 'with keyword args' do
@@ -558,5 +578,13 @@ def initialize(other)
558578
end
559579
end
560580
end
581+
582+
context 'autoinject in a module' do
583+
it 'raises exception' do
584+
expect {
585+
mod.include Test::AutoInject.kwargs[:one, :two]
586+
}.to raise_error(Dry::AutoInject::Error, /cannot inject/)
587+
end
588+
end
561589
end
562590
end

0 commit comments

Comments
 (0)