Skip to content

Commit bc587fc

Browse files
committed
Improve SCP exception handling when canceling transfers in progress
This commit improves exception handling triggered when a transfer is cancelled while in progress, either by a timeout or as a result of a user triggering a KeyboardInterrupt. As part of this, an "Unknown exception" should no longer be logged for SCP server tasks which are cancelled. SCP client tasks should also no longer raise exceptions from a timeout or KeyboardInterrupt which is properly caught out at the application level.
1 parent 78250b3 commit bc587fc

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

asyncssh/scp.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,10 @@ def handle_error(self, exc: Exception) -> None:
383383

384384
self.logger.debug1('Handling SCP error: %s', str(exc))
385385

386-
if getattr(exc, 'fatal', False) or self._error_handler is None:
387-
raise exc from None
388-
elif self._error_handler:
386+
if self._error_handler and not getattr(exc, 'fatal', False):
389387
self._error_handler(exc)
388+
elif not self._server:
389+
raise exc
390390

391391
async def close(self, cancelled: bool = False) -> None:
392392
"""Close an SCP session"""
@@ -395,12 +395,13 @@ async def close(self, cancelled: bool = False) -> None:
395395

396396
if cancelled:
397397
self._writer.channel.abort()
398-
elif self._server:
399-
cast('SSHServerChannel', self._writer.channel).exit(0)
400398
else:
401-
self._writer.close()
399+
if self._server:
400+
cast('SSHServerChannel', self._writer.channel).exit(0)
401+
else:
402+
self._writer.close()
402403

403-
await self._writer.channel.wait_closed()
404+
await self._writer.wait_closed()
404405

405406

406407
class _SCPSource(_SCPHandler):
@@ -665,7 +666,8 @@ async def _recv_files(self, srcpath: bytes, dstpath: bytes) -> None:
665666

666667
try:
667668
if action in b'\x01\x02':
668-
raise _scp_error(SFTPFailure, args, fatal=action != b'\x01',
669+
raise _scp_error(SFTPFailure, args,
670+
fatal=action != b'\x01',
669671
suppress_send=True)
670672
elif action == b'T':
671673
if self._preserve:
@@ -754,7 +756,8 @@ def _handle_error(self, exc: Exception) -> None:
754756
"""Handle an SCP error"""
755757

756758
if isinstance(exc, BrokenPipeError):
757-
exc = _scp_error(SFTPConnectionLost, 'Connection lost', fatal=True)
759+
exc = _scp_error(SFTPConnectionLost, 'Connection lost',
760+
fatal=True, suppress_send=True)
758761

759762
self.logger.debug1('Handling SCP error: %s', str(exc))
760763

@@ -797,7 +800,7 @@ async def _copy_file(self, path: bytes, size: int) -> None:
797800

798801
if not data:
799802
raise _scp_error(SFTPConnectionLost, 'Connection lost',
800-
fatal=True)
803+
fatal=True, suppress_send=True)
801804

802805
await self._sink.send_data(data)
803806
offset += len(data)

0 commit comments

Comments
 (0)