Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websocket disconnect errors instead of handling gracefully #201

Open
bryaan opened this issue Jun 5, 2024 · 5 comments
Open

Websocket disconnect errors instead of handling gracefully #201

bryaan opened this issue Jun 5, 2024 · 5 comments

Comments

@bryaan
Copy link

bryaan commented Jun 5, 2024

When my websocket client disconnects, the server throws an error:

 Info: 2024-06-04 21:41:58 AppWebSockerServer - WS Client Disconnected
┌ Error: 2024-06-04 21:41:59 handle_connection handler error.
│
│ ===========================
│ HTTP Error message:
│
│ ERROR: TaskFailedException
│ Stacktrace:
│  [1] wait
│    @ ./task.jl:352 [inlined]
│  [2] (::Oxygen.Core.var"#17#20"{Oxygen.Core.var"#15#16"{Oxygen.Core.var"#29#31"{Oxygen.Core.var"#40#44"{Oxygen.Core.AutoDoc.var"#2#4"{Oxygen.Core.var"#34#37"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(Main.LunaStox.ServerHandlers.CorsMiddleware)}, Dict{String, Tuple}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}})(stream::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}})
│    @ Oxygen.Core ~/.julia/packages/Oxygen/LWjgB/src/core.jl:225
│  [3] #invokelatest#2
│    @ ./essentials.jl:887 [inlined]
│  [4] invokelatest
│    @ ./essentials.jl:884 [inlined]
│  [5] handle_connection(f::Function, c::HTTP.Connections.Connection{Sockets.TCPSocket}, listener::HTTP.Servers.Listener{Nothing, Sockets.TCPServer}, readtimeout::Int64, access_log::Function)
│    @ HTTP.Servers ~/.julia/packages/HTTP/sJD5V/src/Servers.jl:469
│  [6] (::HTTP.Servers.var"#16#17"{Oxygen.Core.var"#17#20"{Oxygen.Core.var"#15#16"{Oxygen.Core.var"#29#31"{Oxygen.Core.var"#40#44"{Oxygen.Core.AutoDoc.var"#2#4"{Oxygen.Core.var"#34#37"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(Main.LunaStox.ServerHandlers.CorsMiddleware)}, Dict{String, Tuple}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}}, HTTP.Servers.Listener{Nothing, Sockets.TCPServer}, Set{HTTP.Connections.Connection}, Int64, Oxygen.Core.var"#25#26", ReentrantLock, Base.Semaphore, HTTP.Connections.Connection{Sockets.TCPSocket}})()
│    @ HTTP.Servers ~/.julia/packages/HTTP/sJD5V/src/Servers.jl:401
│
│     nested task error: TaskFailedException
│     Stacktrace:
│      [1] wait
│        @ ./task.jl:352 [inlined]
│      [2] (::Oxygen.Core.var"#18#21"{HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}, Oxygen.Core.var"#15#16"{Oxygen.Core.var"#29#31"{Oxygen.Core.var"#40#44"{Oxygen.Core.AutoDoc.var"#2#4"{Oxygen.Core.var"#34#37"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(Main.LunaStox.ServerHandlers.CorsMiddleware)}, Dict{String, Tuple}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}})()
│        @ Oxygen.Core ~/.julia/packages/Oxygen/LWjgB/src/core.jl:223
│
│         nested task error: IOError: stream is closed or unusable
│         Stacktrace:
│           [1] check_open
│             @ ./stream.jl:388 [inlined]
│           [2] uv_write_async(s::Sockets.TCPSocket, p::Ptr{UInt8}, n::UInt64)
│             @ Base ./stream.jl:1074
│           [3] uv_write(s::Sockets.TCPSocket, p::Ptr{UInt8}, n::UInt64)
│             @ Base ./stream.jl:1037
│           [4] unsafe_write(s::Sockets.TCPSocket, p::Ptr{UInt8}, n::UInt64)
│             @ Base ./stream.jl:1120
│           [5] unsafe_write
│             @ ~/.julia/packages/HTTP/sJD5V/src/Connections.jl:132 [inlined]
│           [6] unsafe_write
│             @ ./io.jl:698 [inlined]
│           [7] write(io::IO, x1::Any, xs::Vararg{Any})
│             @ Base ./io.jl:721 [inlined]
│           [8] writeheaders(io::HTTP.Connections.Connection{Sockets.TCPSocket}, m::HTTP.Messages.Response, buf::IOBuffer)
│             @ HTTP.Messages ~/.julia/packages/HTTP/sJD5V/src/Messages.jl:503
│           [9] writeheaders(io::IO, m::HTTP.Messages.Message, buf::IOBuffer)
│             @ HTTP.Messages ~/.julia/packages/HTTP/sJD5V/src/Messages.jl:494 [inlined]
│          [10] startwrite(http::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}})
│             @ HTTP.Streams ~/.julia/packages/HTTP/sJD5V/src/Streams.jl:79
│          [11] (::HTTP.Handlers.var"#1#2"{Oxygen.Core.var"#12#14"{Oxygen.Core.var"#29#31"{Oxygen.Core.var"#40#44"{Oxygen.Core.AutoDoc.var"#2#4"{Oxygen.Core.var"#34#37"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(Main.LunaStox.ServerHandlers.CorsMiddleware)}, Dict{String, Tuple}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}, Sockets.IPv4, HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}}})(stream::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}})
│             @ HTTP.Handlers ~/.julia/packages/HTTP/sJD5V/src/Handlers.jl:60
│          [12] #15
│             @ Oxygen.Core ~/.julia/packages/Oxygen/LWjgB/src/core.jl:208 [inlined]
│          [13] (::Oxygen.Core.var"#19#22"{HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}, Oxygen.Core.var"#15#16"{Oxygen.Core.var"#29#31"{Oxygen.Core.var"#40#44"{Oxygen.Core.AutoDoc.var"#2#4"{Oxygen.Core.var"#34#37"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(Main.LunaStox.ServerHandlers.CorsMiddleware)}, Dict{String, Tuple}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}})()
│             @ Oxygen.Core ~/.julia/packages/Oxygen/LWjgB/src/core.jl:222
│   request =
│    HTTP.Messages.Request:
│    """
│    GET /ws/scanner HTTP/1.1
│    Host: 127.0.0.1:7820
│    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0
│    Accept: */*
│    Accept-Language: en-US,en;q=0.5
│    Accept-Encoding: gzip, deflate, br
│    Sec-WebSocket-Version: 13
│    Origin: http://localhost:5173
│    Sec-WebSocket-Extensions: permessage-deflate
│    Sec-WebSocket-Key: 7LG0jbS9Ud1oP9uTOFKCrA==
│    DNT: 1
│    Connection: keep-alive, Upgrade
│    Sec-Fetch-Dest: empty
│    Sec-Fetch-Mode: websocket
│    Sec-Fetch-Site: cross-site
│    Pragma: no-cache
│    Cache-Control: no-cache
│    Upgrade: websocket
│
│    """
└ @ HTTP.Servers ~/.julia/packages/HTTP/sJD5V/src/Servers.jl:483
@ndortega
Copy link
Member

ndortega commented Jun 5, 2024

Hi @bryaan,

What kind of behavior would expect to get when a client forcefully disconnects? It should be simple enough to explicitly catch and hide this error since it's so common

@bryaan
Copy link
Author

bryaan commented Jun 7, 2024

Yes, that sounds like a good default.

@bryaan
Copy link
Author

bryaan commented Jun 20, 2024

Any progress on this? really ugly to see these common messages in my error log.

@bryaan
Copy link
Author

bryaan commented Jun 20, 2024

I've tried to fix this like so, but the error still bubbles up.

function _try_send(ws, message)
    try
        send(ws, message)
    catch e
    end
end

@arlowhite
Copy link

HTTP canceled request also has a big error. It would be nice to hide or simplify these in the log as well:

┌ Error: handle_connection handler error.
│
│ ===========================
│ HTTP Error message:
│
│ ERROR: TaskFailedException
│ Stacktrace:
│  [1] wait(t::Task)
│    @ Base .\task.jl:370
│  [2] (::Oxygen.Core.var"#14#17"{Oxygen.Core.var"#12#13"{Oxygen.Core.var"#26#28"{Oxygen.Core.var"#37#41"{Oxygen.Core.Middleware.var"#2#4"{Oxygen.Core.var"#31#34"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(ReefGuideAPI.CorsMiddleware)}, Dict{String, Tuple}, Dict{String, Function}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}})(stream::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}})
│    @ Oxygen.Core C:\Users\awhite\.julia\packages\Oxygen\RkoDD\src\core.jl:219
│  [3] #invokelatest#2
│    @ .\essentials.jl:1055 [inlined]
│  [4] invokelatest
│    @ .\essentials.jl:1052 [inlined]
│  [5] handle_connection(f::Function, c::HTTP.Connections.Connection{Sockets.TCPSocket}, listener::HTTP.Servers.Listener{Nothing, Sockets.TCPServer}, readtimeout::Int64, access_log::Function)
│    @ HTTP.Servers C:\Users\awhite\.julia\packages\HTTP\sJD5V\src\Servers.jl:469
│  [6] (::HTTP.Servers.var"#16#17"{Oxygen.Core.var"#14#17"{Oxygen.Core.var"#12#13"{Oxygen.Core.var"#26#28"{Oxygen.Core.var"#37#41"{Oxygen.Core.Middleware.var"#2#4"{Oxygen.Core.var"#31#34"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(ReefGuideAPI.CorsMiddleware)}, Dict{String, Tuple}, Dict{String, Function}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}}, HTTP.Servers.Listener{Nothing, Sockets.TCPServer}, Set{HTTP.Connections.Connection}, Int64, Oxygen.Core.var"#22#23", ReentrantLock, Base.Semaphore, HTTP.Connections.Connection{Sockets.TCPSocket}})()
│    @ HTTP.Servers C:\Users\awhite\.julia\packages\HTTP\sJD5V\src\Servers.jl:401
│
│     nested task error: TaskFailedException
│     Stacktrace:
│      [1] wait(t::Task)
│        @ Base .\task.jl:370
│      [2] (::Oxygen.Core.var"#15#18"{HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}, Oxygen.Core.var"#12#13"{Oxygen.Core.var"#26#28"{Oxygen.Core.var"#37#41"{Oxygen.Core.Middleware.var"#2#4"{Oxygen.Core.var"#31#34"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(ReefGuideAPI.CorsMiddleware)}, Dict{String, Tuple}, Dict{String, Function}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}})()
│        @ Oxygen.Core C:\Users\awhite\.julia\packages\Oxygen\RkoDD\src\core.jl:217
│
│         nested task error: IOError: write: operation canceled (ECANCELED)
│         Stacktrace:
│          [1] uv_write(s::Sockets.TCPSocket, p::Ptr{UInt8}, n::UInt64)
│            @ Base .\stream.jl:1091
│          [2] unsafe_write(s::Sockets.TCPSocket, p::Ptr{UInt8}, n::UInt64)
│            @ Base .\stream.jl:1145
│          [3] unsafe_write
│            @ C:\Users\awhite\.julia\packages\HTTP\sJD5V\src\Connections.jl:132 [inlined]
│          [4] unsafe_write(http::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}, p::Ptr{UInt8}, n::UInt64)
│            @ HTTP.Streams C:\Users\awhite\.julia\packages\HTTP\sJD5V\src\Streams.jl:93
│          [5] write
│            @ .\strings\io.jl:248 [inlined]
│          [6] write(io::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}, s::Base.CodeUnits{UInt8, String})
│            @ Base .\strings\basic.jl:807
│          [7] (::HTTP.Handlers.var"#1#2"{Oxygen.Core.var"#9#11"{Oxygen.Core.var"#26#28"{Oxygen.Core.var"#37#41"{Oxygen.Core.Middleware.var"#2#4"{Oxygen.Core.var"#31#34"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(ReefGuideAPI.CorsMiddleware)}, Dict{String, Tuple}, Dict{String, Function}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}, Sockets.IPv4, HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}}})(stream::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}})
│            @ HTTP.Handlers C:\Users\awhite\.julia\packages\HTTP\sJD5V\src\Handlers.jl:61
│          [8] #12
│            @ C:\Users\awhite\.julia\packages\Oxygen\RkoDD\src\core.jl:202 [inlined]
│          [9] (::Oxygen.Core.var"#16#19"{HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.Connections.Connection{Sockets.TCPSocket}}, Oxygen.Core.var"#12#13"{Oxygen.Core.var"#26#28"{Oxygen.Core.var"#37#41"{Oxygen.Core.Middleware.var"#2#4"{Oxygen.Core.var"#31#34"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Bool, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, Vector{typeof(ReefGuideAPI.CorsMiddleware)}, Dict{String, Tuple}, Dict{String, Function}}, Oxygen.Core.AppContext.Service, Bool}, HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}, String}}})()
│            @ Oxygen.Core C:\Users\awhite\.julia\packages\Oxygen\RkoDD\src\core.jl:216
│   request =
│    HTTP.Messages.Request:
│    """
│    GET /tile/10/927/558?region=Cairns-Cooktown&rtype=slopes&criteria_names=Depth%2CSlope%2CTurbidity%2CWavesHs%2CWavesTp&lb=-8%2C0%2C0%2C0%2C0&ub=0%2C14%2C30%2C0.5%2C6 HTTP/1.1
│    Host: localhost:8000
│    Connection: keep-alive
│    Pragma: no-cache
│    Cache-Control: no-cache
│    sec-ch-ua-platform: "Windows"
│    Authorization: ******
│    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36
│    sec-ch-ua: "Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"
│    sec-ch-ua-mobile: ?0
│    Accept: */*
│    Origin: http://localhost:4200
│    Sec-Fetch-Site: same-site
│    Sec-Fetch-Mode: cors
│    Sec-Fetch-Dest: empty
│    Referer: http://localhost:4200/
│    Accept-Encoding: gzip, deflate, br, zstd
│    Accept-Language: en-US,en;q=0.9
│
│    """
└ @ HTTP.Servers C:\Users\awhite\.julia\packages\HTTP\sJD5V\src\Servers.jl:483

Note: working on a map app, so these are frequent when you pan/zoom and the map component decides to cancel a tile request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants