@@ -73,11 +73,20 @@ defmodule Srh.Http.CommandHandler do
7373 { :ok , result_map } ->
7474 [ result_map | responses ]
7575
76+ { :connection_error , result } ->
77+ { :connection_error , result }
78+
7679 { :redis_error , result } ->
7780 [ result | responses ]
7881 end
7982
80- dispatch_command_array ( rest , connection_info , updated_responses )
83+ case updated_responses do
84+ { :connection_error , result } ->
85+ { :connection_error , result }
86+
87+ _ ->
88+ dispatch_command_array ( rest , connection_info , updated_responses )
89+ end
8190 end
8291
8392 defp dispatch_command_array ( [ ] , _connection_info , responses ) do
@@ -95,43 +104,56 @@ defmodule Srh.Http.CommandHandler do
95104 # Borrow a client, then run all of the commands (wrapped in MULTI and EXEC)
96105 worker_pid = Client . borrow_worker ( client_pid )
97106
98- wrapped_command_array = [ [ "MULTI" ] | command_array ]
99- do_dispatch_command_transaction_array ( wrapped_command_array , worker_pid , responses )
107+ # We are manually going to invoke the MULTI, because there might be a connection error to the Redis server.
108+ # In that case, we don't want the error to be wound up in the array of errors,
109+ # we instead want to return the error immediately.
110+ case ClientWorker . redis_command ( worker_pid , [ "MULTI" ] ) do
111+ { :ok , _ } ->
112+ do_dispatch_command_transaction_array ( command_array , worker_pid , responses )
100113
101- # Now manually run the EXEC - this is what contains the information to form the response, not the above
102- result = case ClientWorker . redis_command ( worker_pid , [ "EXEC" ] ) do
103- { :ok , res } ->
104- {
105- :ok ,
106- res
107- |> Enum . map ( & ( % { result: & 1 } ) )
108- }
109- # TODO: Can there be any inline errors here? Wouldn't they fail the whole tx?
114+ # Now manually run the EXEC - this is what contains the information to form the response, not the above
115+ result =
116+ case ClientWorker . redis_command ( worker_pid , [ "EXEC" ] ) do
117+ { :ok , res } ->
118+ {
119+ :ok ,
120+ res
121+ |> Enum . map ( & % { result: & 1 } )
122+ }
123+
124+ { :error , error } ->
125+ decode_error ( error , srh_id )
126+ end
127+
128+ Client . return_worker ( client_pid , worker_pid )
129+
130+ # Fire back the result here, because the initial Multi was successful
131+ result
110132
111133 { :error , error } ->
112- { :redis_error , % { error: error . message } }
134+ decode_error ( error , srh_id )
113135 end
114136
115- Client . return_worker ( client_pid , worker_pid )
116-
117- result
118137 { :error , msg } ->
119138 { :server_error , msg }
120139 end
121140 end
122141
123- defp do_dispatch_command_transaction_array ( [ current | rest ] , worker_pid , responses ) when is_pid ( worker_pid ) do
124- updated_responses = case ClientWorker . redis_command ( worker_pid , current ) do
125- { :ok , res } ->
126- [ % { result: res } | responses ]
127-
128- { :error , error } ->
129- [
130- % {
131- error: error . message
132- } | responses
133- ]
134- end
142+ defp do_dispatch_command_transaction_array ( [ current | rest ] , worker_pid , responses )
143+ when is_pid ( worker_pid ) do
144+ updated_responses =
145+ case ClientWorker . redis_command ( worker_pid , current ) do
146+ { :ok , res } ->
147+ [ % { result: res } | responses ]
148+
149+ { :error , error } ->
150+ [
151+ % {
152+ error: error . message
153+ }
154+ | responses
155+ ]
156+ end
135157
136158 do_dispatch_command_transaction_array ( rest , worker_pid , updated_responses )
137159 end
@@ -154,16 +176,34 @@ defmodule Srh.Http.CommandHandler do
154176 { :ok , % { result: res } }
155177
156178 { :error , error } ->
157- {
158- :redis_error ,
159- % {
160- error: error . message
161- }
162- }
179+ decode_error ( error , srh_id )
163180 end
164181
165182 { :error , msg } ->
166183 { :server_error , msg }
167184 end
168185 end
186+
187+ # Figure out if it's an actual Redis error or a Redix error
188+ defp decode_error ( error , srh_id ) do
189+ case error do
190+ % { reason: :closed } ->
191+ IO . puts (
192+ "WARNING: SRH was unable to connect to the Redis server. Please make sure it is running, and the connection information is correct. SRH ID: #{ srh_id } "
193+ )
194+
195+ {
196+ :connection_error ,
197+ "SRH: Unable to connect to the Redis server. See SRH logs for more information."
198+ }
199+
200+ _ ->
201+ {
202+ :redis_error ,
203+ % {
204+ error: error . message
205+ }
206+ }
207+ end
208+ end
169209end
0 commit comments