Skip to content

Commit 7e392ff

Browse files
authored
Merge pull request #54 from julia-vscode/better-error-handling
Improve error handling in @async
2 parents b6042f1 + 2d23be1 commit 7e392ff

File tree

2 files changed

+55
-39
lines changed

2 files changed

+55
-39
lines changed

src/core.jl

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,17 @@ function Base.run(x::JSONRPCEndpoint)
9191
x.status == :idle || error("Endpoint is not idle.")
9292

9393
x.write_task = @async try
94-
for msg in x.out_msg_queue
95-
if isopen(x.pipe_out)
96-
write_transport_layer(x.pipe_out, msg)
97-
else
98-
# TODO Reconsider at some point whether this should be treated as an error.
99-
break
94+
try
95+
for msg in x.out_msg_queue
96+
if isopen(x.pipe_out)
97+
write_transport_layer(x.pipe_out, msg)
98+
else
99+
# TODO Reconsider at some point whether this should be treated as an error.
100+
break
101+
end
100102
end
103+
finally
104+
close(x.out_msg_queue)
101105
end
102106
catch err
103107
bt = catch_backtrace()
@@ -106,37 +110,39 @@ function Base.run(x::JSONRPCEndpoint)
106110
else
107111
Base.display_error(stderr, err, bt)
108112
end
109-
finally
110-
close(x.out_msg_queue)
111113
end
112114

113115
x.read_task = @async try
114-
while true
115-
message = read_transport_layer(x.pipe_in)
116-
117-
if message === nothing || x.status == :closed
118-
break
119-
end
116+
try
117+
while true
118+
message = read_transport_layer(x.pipe_in)
120119

121-
message_dict = JSON.parse(message)
120+
if message === nothing || x.status == :closed
121+
break
122+
end
122123

123-
if haskey(message_dict, "method")
124-
try
125-
put!(x.in_msg_queue, message_dict)
126-
catch err
127-
if err isa InvalidStateException
128-
break
129-
else
130-
rethrow(err)
124+
message_dict = JSON.parse(message)
125+
126+
if haskey(message_dict, "method")
127+
try
128+
put!(x.in_msg_queue, message_dict)
129+
catch err
130+
if err isa InvalidStateException
131+
break
132+
else
133+
rethrow(err)
134+
end
131135
end
132-
end
133-
else
134-
# This must be a response
135-
id_of_request = message_dict["id"]
136+
else
137+
# This must be a response
138+
id_of_request = message_dict["id"]
136139

137-
channel_for_response = x.outstanding_requests[id_of_request]
138-
put!(channel_for_response, message_dict)
140+
channel_for_response = x.outstanding_requests[id_of_request]
141+
put!(channel_for_response, message_dict)
142+
end
139143
end
144+
finally
145+
close(x.in_msg_queue)
140146
end
141147
catch err
142148
bt = catch_backtrace()
@@ -145,8 +151,6 @@ function Base.run(x::JSONRPCEndpoint)
145151
else
146152
Base.display_error(stderr, err, bt)
147153
end
148-
finally
149-
close(x.in_msg_queue)
150154
end
151155

152156
x.status = :running

test/test_typed.jl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@testset "Message dispatcher" begin
22

33
if Sys.iswindows()
4-
global_socket_name = "\\\\.\\pipe\\jsonrpc-testrun"
4+
global_socket_name1 = "\\\\.\\pipe\\jsonrpc-testrun1"
55
elseif Sys.isunix()
6-
global_socket_name = joinpath(tempdir(), "jsonrpc-testrun")
6+
global_socket_name1 = joinpath(tempdir(), "jsonrpc-testrun1")
77
else
88
error("Unknown operating system.")
99
end
@@ -16,8 +16,8 @@
1616

1717
server_is_up = Base.Condition()
1818

19-
server_task = @async begin
20-
server = listen(global_socket_name)
19+
server_task = @async try
20+
server = listen(global_socket_name1)
2121
notify(server_is_up)
2222
sock = accept(server)
2323
global conn = JSONRPC.JSONRPCEndpoint(sock, sock)
@@ -35,11 +35,13 @@
3535
for msg in conn
3636
JSONRPC.dispatch_msg(conn, msg_dispatcher, msg)
3737
end
38+
catch err
39+
Base.display_error(stderr, err, catch_backtrace())
3840
end
3941

4042
wait(server_is_up)
4143

42-
sock2 = connect(global_socket_name)
44+
sock2 = connect(global_socket_name1)
4345
conn2 = JSONRPCEndpoint(sock2, sock2)
4446

4547
run(conn2)
@@ -61,10 +63,18 @@
6163

6264
# Now we test a faulty server
6365

66+
if Sys.iswindows()
67+
global_socket_name2 = "\\\\.\\pipe\\jsonrpc-testrun2"
68+
elseif Sys.isunix()
69+
global_socket_name2 = joinpath(tempdir(), "jsonrpc-testrun2")
70+
else
71+
error("Unknown operating system.")
72+
end
73+
6474
server_is_up = Base.Condition()
6575

66-
server_task2 = @async begin
67-
server = listen(global_socket_name)
76+
server_task2 = @async try
77+
server = listen(global_socket_name2)
6878
notify(server_is_up)
6979
sock = accept(server)
7080
global conn = JSONRPC.JSONRPCEndpoint(sock, sock)
@@ -77,11 +87,13 @@
7787
for msg in conn
7888
@test_throws ErrorException("The handler for the 'request2' request returned a value of type $Int, which is not a valid return type according to the request definition.") JSONRPC.dispatch_msg(conn, msg_dispatcher, msg)
7989
end
90+
catch err
91+
Base.display_error(stderr, err, catch_backtrace())
8092
end
8193

8294
wait(server_is_up)
8395

84-
sock2 = connect(global_socket_name)
96+
sock2 = connect(global_socket_name2)
8597
conn2 = JSONRPCEndpoint(sock2, sock2)
8698

8799
run(conn2)

0 commit comments

Comments
 (0)