From 7e40d176ae58803c7fe209c6d2a6cd7f29eb9af6 Mon Sep 17 00:00:00 2001 From: Boss-1s <95505913+Boss-1s@users.noreply.github.com> Date: Fri, 26 Sep 2025 18:19:03 -0500 Subject: [PATCH 1/5] Add note when encountering WebSocketBadStatusException Encountering a WebSocketBadStatusException most likely means that Scratch's cloud is down. Signed-off-by: Boss-1s <95505913+Boss-1s@users.noreply.github.com> --- scratchattach/cloud/_base.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/scratchattach/cloud/_base.py b/scratchattach/cloud/_base.py index ed71c9b5..8e3575aa 100644 --- a/scratchattach/cloud/_base.py +++ b/scratchattach/cloud/_base.py @@ -335,20 +335,22 @@ def _handshake(self): self._send_packet(packet) def connect(self): - self.websocket = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) - self.websocket.connect( - self.cloud_host, - cookie=self.cookie, - origin=self.origin, - enable_multithread=True, - timeout=self.ws_timeout, - header=self.header - ) - self._handshake() - self.active_connection = True - if self.print_connect_message: - print("Connected to cloud server ", self.cloud_host) - + try: + self.websocket = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) + self.websocket.connect( + self.cloud_host, + cookie=self.cookie, + origin=self.origin, + enable_multithread=True, + timeout=self.ws_timeout, + header=self.header + ) + self._handshake() + self.active_connection = True + if self.print_connect_message: + print("Connected to cloud server ", self.cloud_host) + except WebSocketBadStatusException as e: + print(f"Error: {e} --- Scratch's Cloud system may be down. Please try again later.") def disconnect(self): self.active_connection = False if self.recorder is not None: From ab5fa4eb9c27c31275e626e7a01048ecc1595820 Mon Sep 17 00:00:00 2001 From: retek <107722825+faretek1@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:56:20 +0100 Subject: [PATCH 2/5] Apply suggestions from code review Signed-off-by: retek <107722825+faretek1@users.noreply.github.com> --- scratchattach/cloud/_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scratchattach/cloud/_base.py b/scratchattach/cloud/_base.py index 8e3575aa..88e1ed44 100644 --- a/scratchattach/cloud/_base.py +++ b/scratchattach/cloud/_base.py @@ -350,7 +350,7 @@ def connect(self): if self.print_connect_message: print("Connected to cloud server ", self.cloud_host) except WebSocketBadStatusException as e: - print(f"Error: {e} --- Scratch's Cloud system may be down. Please try again later.") + raise WebSocketBadStatusException(f"Error: Scratch's Cloud system may be down. Please try again later.") from e def disconnect(self): self.active_connection = False if self.recorder is not None: From 0efb5070fa7bcf5e194fada531a78909b9b53234 Mon Sep 17 00:00:00 2001 From: Boss-1s <95505913+Boss-1s@users.noreply.github.com> Date: Sat, 27 Sep 2025 18:40:06 -0500 Subject: [PATCH 3/5] Update cloud.py Signed-off-by: Boss-1s <95505913+Boss-1s@users.noreply.github.com> --- scratchattach/cloud/cloud.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scratchattach/cloud/cloud.py b/scratchattach/cloud/cloud.py index 05d04169..419ae632 100644 --- a/scratchattach/cloud/cloud.py +++ b/scratchattach/cloud/cloud.py @@ -26,7 +26,10 @@ def __init__(self, *, project_id, _session=None): def connect(self): self._assert_auth() # Connecting to Scratch's cloud websocket requires a login to the Scratch website - super().connect() + try: + super().connect() + except WebSocketBadStatusException as e: + raise WebSocketBadStatusException(f"Error: Scratch's Cloud system may be down. Please try again later.") from e def set_var(self, variable, value): self._assert_auth() # Setting a cloud var requires a login to the Scratch website From 44f48052d095ca2b1a1ff057382290b66d0bf5ad Mon Sep 17 00:00:00 2001 From: TheCommCraft <79996518+TheCommCraft@users.noreply.github.com> Date: Sun, 28 Sep 2025 10:30:31 +0200 Subject: [PATCH 4/5] Only warn if scratch cloud is used Signed-off-by: TheCommCraft <79996518+TheCommCraft@users.noreply.github.com> --- scratchattach/cloud/_base.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/scratchattach/cloud/_base.py b/scratchattach/cloud/_base.py index 88e1ed44..ed71c9b5 100644 --- a/scratchattach/cloud/_base.py +++ b/scratchattach/cloud/_base.py @@ -335,22 +335,20 @@ def _handshake(self): self._send_packet(packet) def connect(self): - try: - self.websocket = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) - self.websocket.connect( - self.cloud_host, - cookie=self.cookie, - origin=self.origin, - enable_multithread=True, - timeout=self.ws_timeout, - header=self.header - ) - self._handshake() - self.active_connection = True - if self.print_connect_message: - print("Connected to cloud server ", self.cloud_host) - except WebSocketBadStatusException as e: - raise WebSocketBadStatusException(f"Error: Scratch's Cloud system may be down. Please try again later.") from e + self.websocket = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) + self.websocket.connect( + self.cloud_host, + cookie=self.cookie, + origin=self.origin, + enable_multithread=True, + timeout=self.ws_timeout, + header=self.header + ) + self._handshake() + self.active_connection = True + if self.print_connect_message: + print("Connected to cloud server ", self.cloud_host) + def disconnect(self): self.active_connection = False if self.recorder is not None: From 7f01c365a3f7cd012b9f8cd4720231e52f605d0b Mon Sep 17 00:00:00 2001 From: faretek Date: Sun, 28 Sep 2025 09:45:19 +0100 Subject: [PATCH 5/5] fix: import exception It seems like the scratch cloud variables are up again, so it can't really be tested anymore. On that note, we should test if new scratchers and banned accounts can still set cloud vars. --- scratchattach/cloud/cloud.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scratchattach/cloud/cloud.py b/scratchattach/cloud/cloud.py index 419ae632..b9070b7d 100644 --- a/scratchattach/cloud/cloud.py +++ b/scratchattach/cloud/cloud.py @@ -8,6 +8,7 @@ from scratchattach.utils import exceptions, commons from scratchattach.site import cloud_activity +from websocket import WebSocketBadStatusException class ScratchCloud(BaseCloud): def __init__(self, *, project_id, _session=None):