From 7235f687b1b83568d873085572545d3fe3f3a64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=C5=81uszczek?= Date: Sun, 22 Mar 2026 13:10:18 +0100 Subject: [PATCH] Read and display HTTP response body on WebSocket handshake failure 400/4xx responses include a body (Content-Length) with the actual error message, which was previously swallowed. Now captured and shown in the RuntimeError so the root cause is visible without --debug. Co-Authored-By: Claude Sonnet 4.6 --- lib/portainer_cli/websocket_exec.rb | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/portainer_cli/websocket_exec.rb b/lib/portainer_cli/websocket_exec.rb index 82d8028..5eb4215 100644 --- a/lib/portainer_cli/websocket_exec.rb +++ b/lib/portainer_cli/websocket_exec.rb @@ -23,11 +23,7 @@ module PortainerCli socket = open_socket - handshake = perform_handshake(socket) - unless handshake.valid? - raise "WebSocket handshake failed: #{handshake.error}\nServer response:\n#{handshake.instance_variable_get(:@data)}" - end - + perform_handshake(socket) run_io_loop(socket) ensure socket&.close rescue nil @@ -59,15 +55,25 @@ module PortainerCli debug "Handshake request:\n#{handshake.to_s.chomp}" socket.write(handshake.to_s) - response = +'' + header_bytes = +'' loop do byte = socket.read(1) break if byte.nil? - response << byte + header_bytes << byte handshake << byte break if handshake.finished? end - debug "Handshake response:\n#{response.chomp}" + debug "Handshake response headers:\n#{header_bytes.chomp}" + + unless handshake.valid? + # Try to read the response body for error details + body = '' + if (len = header_bytes.match(/Content-Length:\s*(\d+)/i)&.[](1)&.to_i) && len > 0 + body = socket.read(len).to_s + end + raise "WebSocket handshake failed: #{handshake.error}\n" \ + "Server response:\n#{header_bytes.chomp}\n#{body}" + end handshake end