Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions samcli/local/docker/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ def create(self, context):
try:
real_container = self.docker_client.containers.create(self._image, **kwargs)
except DockerAPIError as ex:
if "port is already allocated" in str(ex):
raise PortAlreadyInUse(str(ex)) from ex

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the issue #9347 (in expected result section), changing the error class to PortAlreadyInUse will mess up downstream error catching. The suggestion was simply to change the message.

raise DockerContainerCreationFailedException(
f"Container creation failed: {ex.explanation}, check template for potential issue"
)
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/local/docker/test_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,23 @@ def test_must_fail_if_already_created(self):
container.create(self.container_context)
self.assertIsNone(container._concurrency_semaphore)

def test_create_raises_port_already_in_use_when_port_allocated(self):
"""Test that create() raises PortAlreadyInUse when Docker reports port is already allocated"""
container = Container(
self.image, self.cmd, self.working_dir, self.host_dir, docker_client=self.mock_docker_client
)

# Mock APIError with "port is already allocated" message (as reported by Finch)
error_msg = 'failed to parse port mapping "0.0.0.0:7311:8080/tcp": bind for 0.0.0.0:7311 failed: port is already allocated'
mock_error = APIError(error_msg)
self.mock_docker_client.containers.create.side_effect = mock_error

with self.assertRaises(PortAlreadyInUse) as context:
container.create(self.container_context)

# Verify the original error is chained
self.assertIs(context.exception.__cause__, mock_error)

@patch("samcli.local.docker.container.os.path.exists")
@patch("samcli.local.docker.container.os.makedirs")
def test_must_make_host_tmp_dir_if_mount_with_write_container_build(self, mock_makedirs, mock_exists):
Expand Down
Loading