diff --git a/ops/model.py b/ops/model.py
index 9412ae9..79af88f 100644
--- a/ops/model.py
+++ b/ops/model.py
@@ -1418,17 +1418,17 @@ class Container:
             #  instance that is in fact 'ready'.
             self._pebble.get_system_info()
         except pebble.ConnectionError as e:
-            logger.debug("Pebble API is not ready; ConnectionError: %s", e.message())
+            logger.debug("Pebble API is not ready; ConnectionError: %s", e)
             return False
         except FileNotFoundError as e:
             # In some cases, charm authors can attempt to hit the Pebble API before it has had the
             # chance to create the UNIX socket in the shared volume.
-            logger.debug("Pebble API is not ready; UNIX socket not found:", str(e))
+            logger.debug("Pebble API is not ready; UNIX socket not found: %s", e)
             return False
         except pebble.APIError as e:
             # An API error is only raised when the Pebble API returns invalid JSON, or the response
             # cannot be read. Both of these are a likely indicator that something is wrong.
-            logger.warning("Pebble API is not ready; APIError: %s", str(e))
+            logger.warning("Pebble API is not ready; APIError: %s", e)
             return False
         return True
 
diff --git a/ops/pebble.py b/ops/pebble.py
index 71de6fb..0c15c3d 100644
--- a/ops/pebble.py
+++ b/ops/pebble.py
@@ -333,14 +333,6 @@ class Error(Exception):
     def __repr__(self):
         return '<{}.{} {}>'.format(type(self).__module__, type(self).__name__, self.args)
 
-    def name(self):
-        """Return a string representation of the model plus class."""
-        return '<{}.{}>'.format(type(self).__module__, type(self).__name__)
-
-    def message(self):
-        """Return the message passed as an argument."""
-        return self.args[0]
-
 
 class TimeoutError(TimeoutError, Error):
     """Raised when a polling timeout occurs."""

diff --git a/ops/testing.py b/ops/testing.py
index d92609b..98507a5 100755
--- a/ops/testing.py
+++ b/ops/testing.py
@@ -1406,6 +1406,7 @@ class _TestingModelBackend:
         if self._resource_dir is not None:
             self._resource_dir.cleanup()
             self._resource_dir = None
+        self._harness_tmp_dir.cleanup()
 
     def _get_resource_dir(self) -> pathlib.Path:
         if self._resource_dir is None:
diff --git a/test/test_model.py b/test/test_model.py
index 173168f..e1ff14d 100755
--- a/test/test_model.py
+++ b/test/test_model.py
@@ -33,7 +33,14 @@ import ops.testing
 from ops import model
 from ops._private import yaml
 from ops.charm import RelationMeta, RelationRole
-from ops.pebble import APIError, FileInfo, FileType, ServiceInfo
+from ops.pebble import (
+    APIError,
+    ConnectionError,
+    FileInfo,
+    FileType,
+    ServiceInfo,
+    SystemInfo,
+)
 
 
 class TestModel(unittest.TestCase):
@@ -1354,8 +1361,9 @@ containers:
         self.container.replan()
         self.assertEqual(self.pebble.requests, [('replan',)])
 
-    def test_get_system_info(self):
-        self.container.can_connect()
+    def test_can_connect(self):
+        self.pebble.responses.append(SystemInfo.from_dict({'version': '1.0.0'}))
+        self.assertTrue(self.container.can_connect())
         self.assertEqual(self.pebble.requests, [('get_system_info',)])
 
     def test_start(self):
@@ -1687,10 +1695,37 @@ containers:
             ('remove_path', '/path/2', True),
         ])
 
-    def test_bare_can_connect_call(self):
-        self.pebble.responses.append('dummy')
+    def test_can_connect_simple(self):
+        self.pebble.responses.append(SystemInfo.from_dict({'version': '1.0.0'}))
         self.assertTrue(self.container.can_connect())
 
+    def test_can_connect_connection_error(self):
+        def raise_error():
+            raise ConnectionError('connection error!')
+        self.pebble.get_system_info = raise_error
+        with self.assertLogs('ops.model', level='DEBUG') as cm:
+            self.assertFalse(self.container.can_connect())
+        self.assertEqual(len(cm.output), 1)
+        self.assertRegex(cm.output[0], r'DEBUG:ops.model:.*: connection error!')
+
+    def test_can_connect_file_not_found_error(self):
+        def raise_error():
+            raise FileNotFoundError('file not found!')
+        self.pebble.get_system_info = raise_error
+        with self.assertLogs('ops.model', level='DEBUG') as cm:
+            self.assertFalse(self.container.can_connect())
+        self.assertEqual(len(cm.output), 1)
+        self.assertRegex(cm.output[0], r'DEBUG:ops.model:.*: file not found!')
+
+    def test_can_connect_api_error(self):
+        def raise_error():
+            raise APIError('body', 404, 'status', 'api error!')
+        self.pebble.get_system_info = raise_error
+        with self.assertLogs('ops.model') as cm:
+            self.assertFalse(self.container.can_connect())
+        self.assertEqual(len(cm.output), 1)
+        self.assertRegex(cm.output[0], r'WARNING:ops.model:.*: api error!')
+
     def test_exec(self):
         self.pebble.responses.append('fake_exec_process')
         p = self.container.exec(
@@ -1759,6 +1794,7 @@ class MockPebbleClient:
 
     def get_system_info(self):
         self.requests.append(('get_system_info',))
+        return self.responses.pop(0)
 
     def replan_services(self):
         self.requests.append(('replan',))
diff --git a/test/test_pebble.py b/test/test_pebble.py
index 924d110..d076795 100644
--- a/test/test_pebble.py
+++ b/test/test_pebble.py
@@ -1248,7 +1248,7 @@ class TestMultipartParser(unittest.TestCase):
                     if not test.error:
                         self.fail('unexpected error:', err)
                         break
-                    self.assertEqual(test.error, err.message())
+                    self.assertEqual(test.error, str(err))
                 else:
                     if test.error:
                         self.fail('missing expected error: {!r}'.format(test.error))

Log format string missing %s in can_connect
When reviewing some unrelated code, I noticed there was an [invalid `logger.debug` format string](https://github.com/canonical/operator/blob/6ee44cfb64d0680ec7e72ad1c746a87a0c63f0c8/ops/model.py#L1148) in the `model.Container.can_connect` code. It does the following:

```python
logger.debug("Pebble API is not ready; UNIX socket not found:", str(e))
```

However, the logging API expects the first argument to be a format string, so there should be a `%s` here, and the logging library gives this exception (not raised, as logging catches exceptions):

```
>>> logger.debug("Pebble API is not ready; UNIX socket not found:", str(e))
--- Logging error ---
Traceback (most recent call last):
  File "/usr/lib/python3.9/logging/__init__.py", line 1083, in emit
    msg = self.format(record)
  File "/usr/lib/python3.9/logging/__init__.py", line 927, in format
    return fmt.format(record)
  File "/usr/lib/python3.9/logging/__init__.py", line 663, in format
    record.message = record.getMessage()
  File "/usr/lib/python3.9/logging/__init__.py", line 367, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
  File "<stdin>", line 1, in <module>
Message: 'Pebble API is not ready; UNIX socket not found:'
Arguments: ('REASON',)
```

In addition, when you use `%s`, you don't need `str(e)`, you can just pass `e` directly, and the `%s` formatting calls `str` (which in turn calls `__str__`). We could update the other `APIError` case to omit this too.

I'm not 100% sure, but from a quick glance it looks like `can_connect` is short on tests. We should probably add tests for each exception case and test that it logged something.

test/test_model.py::TestContainerPebble::test_can_connect_file_not_found_error
test/test_model.py::TestModel::test_active_message_default test/test_model.py::TestModel::test_app_immutable test/test_model.py::TestModel::test_app_relation_data_modify_local_as_leader test/test_model.py::TestModel::test_app_relation_data_modify_local_as_minion test/test_model.py::TestModel::test_base_status_instance_raises test/test_model.py::TestModel::test_config test/test_model.py::TestModel::test_config_immutable test/test_model.py::TestModel::test_get_app_relation_data test/test_model.py::TestModel::test_get_relation test/test_model.py::TestModel::test_invalid_type_relation_data test/test_model.py::TestModel::test_is_leader test/test_model.py::TestModel::test_local_set_valid_app_status test/test_model.py::TestModel::test_local_set_valid_unit_status test/test_model.py::TestModel::test_model_attributes test/test_model.py::TestModel::test_model_name_from_backend test/test_model.py::TestModel::test_our_unit_is_our test/test_model.py::TestModel::test_peer_relation_app test/test_model.py::TestModel::test_pod_immutable test/test_model.py::TestModel::test_pod_spec test/test_model.py::TestModel::test_relation_data_access_peer_leader test/test_model.py::TestModel::test_relation_data_access_peer_minion test/test_model.py::TestModel::test_relation_data_del_key test/test_model.py::TestModel::test_relation_data_del_missing_key test/test_model.py::TestModel::test_relation_data_modify_our test/test_model.py::TestModel::test_relation_data_modify_remote test/test_model.py::TestModel::test_relation_data_type_check test/test_model.py::TestModel::test_relation_local_app_data_readability_follower test/test_model.py::TestModel::test_relation_local_app_data_readability_leader test/test_model.py::TestModel::test_relation_no_units test/test_model.py::TestModel::test_relation_set_fail test/test_model.py::TestModel::test_relations_immutable test/test_model.py::TestModel::test_relations_keys test/test_model.py::TestModel::test_remote_app_relation_data test/test_model.py::TestModel::test_remote_app_status test/test_model.py::TestModel::test_remote_unit_status test/test_model.py::TestModel::test_remote_units_is_our test/test_model.py::TestModel::test_resources test/test_model.py::TestModel::test_resources_immutable test/test_model.py::TestModel::test_set_app_status_invalid test/test_model.py::TestModel::test_set_app_status_non_leader_raises test/test_model.py::TestModel::test_set_unit_status_invalid test/test_model.py::TestModel::test_status_eq test/test_model.py::TestModel::test_status_repr test/test_model.py::TestModel::test_storage test/test_model.py::TestModel::test_storages_immutable test/test_model.py::TestModel::test_unit_immutable test/test_model.py::TestModel::test_unit_relation_data test/test_model.py::TestModel::test_workload_version test/test_model.py::TestModel::test_workload_version_invalid test/test_model.py::test_recursive_list[case0] test/test_model.py::test_recursive_list[case1] test/test_model.py::test_recursive_list[case2] test/test_model.py::test_recursive_push_and_pull[case0] test/test_model.py::test_recursive_push_and_pull[case1] test/test_model.py::test_recursive_push_and_pull[case2] test/test_model.py::test_recursive_push_and_pull[case3] test/test_model.py::test_recursive_push_and_pull[case4] test/test_model.py::test_recursive_push_and_pull[case5] test/test_model.py::test_recursive_push_and_pull[case6] test/test_model.py::test_recursive_push_and_pull[case7] test/test_model.py::test_recursive_push_and_pull[case8] test/test_model.py::TestApplication::test_mocked_get_services test/test_model.py::TestApplication::test_planned_units test/test_model.py::TestApplication::test_planned_units_garbage_values test/test_model.py::TestApplication::test_planned_units_override test/test_model.py::TestApplication::test_planned_units_user_set test/test_model.py::TestContainers::test_unit_containers test/test_model.py::TestContainers::test_unit_get_container test/test_model.py::TestContainerPebble::test_add_layer test/test_model.py::TestContainerPebble::test_autostart test/test_model.py::TestContainerPebble::test_can_connect test/test_model.py::TestContainerPebble::test_can_connect_api_error test/test_model.py::TestContainerPebble::test_can_connect_connection_error test/test_model.py::TestContainerPebble::test_can_connect_simple test/test_model.py::TestContainerPebble::test_exec test/test_model.py::TestContainerPebble::test_get_check test/test_model.py::TestContainerPebble::test_get_checks test/test_model.py::TestContainerPebble::test_get_plan test/test_model.py::TestContainerPebble::test_get_service test/test_model.py::TestContainerPebble::test_get_services test/test_model.py::TestContainerPebble::test_list_files test/test_model.py::TestContainerPebble::test_make_dir test/test_model.py::TestContainerPebble::test_pull test/test_model.py::TestContainerPebble::test_push test/test_model.py::TestContainerPebble::test_remove_path test/test_model.py::TestContainerPebble::test_replan test/test_model.py::TestContainerPebble::test_restart test/test_model.py::TestContainerPebble::test_restart_fallback test/test_model.py::TestContainerPebble::test_restart_fallback_non_400_error test/test_model.py::TestContainerPebble::test_restart_no_arguments test/test_model.py::TestContainerPebble::test_send_signal test/test_model.py::TestContainerPebble::test_socket_path test/test_model.py::TestContainerPebble::test_start test/test_model.py::TestContainerPebble::test_start_no_arguments test/test_model.py::TestContainerPebble::test_stop test/test_model.py::TestContainerPebble::test_stop_no_arguments test/test_model.py::TestContainerPebble::test_type_errors test/test_model.py::TestModelBindings::test_binding_by_relation test/test_model.py::TestModelBindings::test_binding_by_relation_name test/test_model.py::TestModelBindings::test_binding_no_iface_name test/test_model.py::TestModelBindings::test_dead_relations test/test_model.py::TestModelBindings::test_empty_bind_addresses test/test_model.py::TestModelBindings::test_empty_interface_info test/test_model.py::TestModelBindings::test_invalid_keys test/test_model.py::TestModelBindings::test_missing_bind_addresses test/test_model.py::TestModelBindings::test_missing_egress_subnets test/test_model.py::TestModelBindings::test_missing_ingress_addresses test/test_model.py::TestModelBindings::test_no_bind_addresses test/test_model.py::TestModelBindings::test_unresolved_ingress_addresses test/test_model.py::TestModelBackend::test_action_fail test/test_model.py::TestModelBackend::test_action_get test/test_model.py::TestModelBackend::test_action_get_error test/test_model.py::TestModelBackend::test_action_log test/test_model.py::TestModelBackend::test_action_log_error test/test_model.py::TestModelBackend::test_action_set test/test_model.py::TestModelBackend::test_action_set_dotted_dict test/test_model.py::TestModelBackend::test_action_set_duplicated_keys test/test_model.py::TestModelBackend::test_action_set_error test/test_model.py::TestModelBackend::test_action_set_key_validation test/test_model.py::TestModelBackend::test_action_set_more_nested test/test_model.py::TestModelBackend::test_action_set_nested test/test_model.py::TestModelBackend::test_application_version_set test/test_model.py::TestModelBackend::test_application_version_set_invalid test/test_model.py::TestModelBackend::test_invalid_metric_label_values test/test_model.py::TestModelBackend::test_invalid_metric_labels test/test_model.py::TestModelBackend::test_invalid_metric_names test/test_model.py::TestModelBackend::test_invalid_metric_values test/test_model.py::TestModelBackend::test_is_leader_refresh test/test_model.py::TestModelBackend::test_juju_log test/test_model.py::TestModelBackend::test_local_set_invalid_status test/test_model.py::TestModelBackend::test_network_get test/test_model.py::TestModelBackend::test_network_get_errors test/test_model.py::TestModelBackend::test_relation_get_juju_version_quirks test/test_model.py::TestModelBackend::test_relation_get_set_is_app_arg test/test_model.py::TestModelBackend::test_relation_remote_app_name_env test/test_model.py::TestModelBackend::test_relation_remote_app_name_script_errors test/test_model.py::TestModelBackend::test_relation_remote_app_name_script_success test/test_model.py::TestModelBackend::test_relation_set_juju_version_quirks test/test_model.py::TestModelBackend::test_relation_tool_errors test/test_model.py::TestModelBackend::test_status_get test/test_model.py::TestModelBackend::test_status_is_app_forced_kwargs test/test_model.py::TestModelBackend::test_status_set_is_app_not_bool_raises test/test_model.py::TestModelBackend::test_storage_tool_errors test/test_model.py::TestModelBackend::test_valid_metrics test/test_model.py::TestLazyMapping::test_invalidate test/test_pebble.py::TestHelpers::test_parse_timestamp test/test_pebble.py::TestTypes::test_api_error test/test_pebble.py::TestTypes::test_change_error test/test_pebble.py::TestTypes::test_change_error_with_task_logs test/test_pebble.py::TestTypes::test_change_from_dict test/test_pebble.py::TestTypes::test_change_id test/test_pebble.py::TestTypes::test_change_init test/test_pebble.py::TestTypes::test_change_state test/test_pebble.py::TestTypes::test_connection_error test/test_pebble.py::TestTypes::test_error test/test_pebble.py::TestTypes::test_file_info_from_dict test/test_pebble.py::TestTypes::test_file_info_init test/test_pebble.py::TestTypes::test_file_type test/test_pebble.py::TestTypes::test_path_error test/test_pebble.py::TestTypes::test_protocol_error test/test_pebble.py::TestTypes::test_system_info_from_dict test/test_pebble.py::TestTypes::test_system_info_init test/test_pebble.py::TestTypes::test_task_from_dict test/test_pebble.py::TestTypes::test_task_id test/test_pebble.py::TestTypes::test_task_init test/test_pebble.py::TestTypes::test_task_progress_from_dict test/test_pebble.py::TestTypes::test_task_progress_init test/test_pebble.py::TestTypes::test_timeout_error test/test_pebble.py::TestTypes::test_warning_from_dict test/test_pebble.py::TestTypes::test_warning_init test/test_pebble.py::TestTypes::test_warning_state test/test_pebble.py::TestPlan::test_checks test/test_pebble.py::TestPlan::test_no_args test/test_pebble.py::TestPlan::test_service_equality test/test_pebble.py::TestPlan::test_services test/test_pebble.py::TestPlan::test_yaml test/test_pebble.py::TestLayer::test_dict test/test_pebble.py::TestLayer::test_layer_service_equality test/test_pebble.py::TestLayer::test_no_args test/test_pebble.py::TestLayer::test_yaml test/test_pebble.py::TestService::test_dict test/test_pebble.py::TestService::test_equality test/test_pebble.py::TestService::test_name_only test/test_pebble.py::TestCheck::test_dict test/test_pebble.py::TestCheck::test_equality test/test_pebble.py::TestCheck::test_level_raw test/test_pebble.py::TestCheck::test_name_only test/test_pebble.py::TestServiceInfo::test_is_running test/test_pebble.py::TestServiceInfo::test_service_info test/test_pebble.py::TestServiceInfo::test_service_startup test/test_pebble.py::TestServiceInfo::test_service_status test/test_pebble.py::TestCheckInfo::test_check_info test/test_pebble.py::TestCheckInfo::test_check_level test/test_pebble.py::TestCheckInfo::test_check_status test/test_pebble.py::TestMultipartParser::test_multipart_parser test/test_pebble.py::TestClient::test_abort_change test/test_pebble.py::TestClient::test_ack_warnings test/test_pebble.py::TestClient::test_add_layer test/test_pebble.py::TestClient::test_add_layer_invalid_type test/test_pebble.py::TestClient::test_autostart_services test/test_pebble.py::TestClient::test_autostart_services_async test/test_pebble.py::TestClient::test_change_error test/test_pebble.py::TestClient::test_checklevel_conversion test/test_pebble.py::TestClient::test_client_init test/test_pebble.py::TestClient::test_get_change test/test_pebble.py::TestClient::test_get_changes test/test_pebble.py::TestClient::test_get_checks_all test/test_pebble.py::TestClient::test_get_checks_filters test/test_pebble.py::TestClient::test_get_plan test/test_pebble.py::TestClient::test_get_services_all test/test_pebble.py::TestClient::test_get_services_names test/test_pebble.py::TestClient::test_get_system_info test/test_pebble.py::TestClient::test_get_warnings test/test_pebble.py::TestClient::test_list_files_itself test/test_pebble.py::TestClient::test_list_files_path test/test_pebble.py::TestClient::test_list_files_pattern test/test_pebble.py::TestClient::test_make_dir_all_options test/test_pebble.py::TestClient::test_make_dir_basic test/test_pebble.py::TestClient::test_make_dir_error test/test_pebble.py::TestClient::test_pull_binary test/test_pebble.py::TestClient::test_pull_boundary_spanning_chunk test/test_pebble.py::TestClient::test_pull_path_error test/test_pebble.py::TestClient::test_pull_protocol_errors test/test_pebble.py::TestClient::test_pull_text test/test_pebble.py::TestClient::test_push_all_options test/test_pebble.py::TestClient::test_push_binary test/test_pebble.py::TestClient::test_push_bytes test/test_pebble.py::TestClient::test_push_path_error test/test_pebble.py::TestClient::test_push_str test/test_pebble.py::TestClient::test_push_text test/test_pebble.py::TestClient::test_push_uid_gid test/test_pebble.py::TestClient::test_remove_path_basic test/test_pebble.py::TestClient::test_remove_path_error test/test_pebble.py::TestClient::test_remove_path_recursive test/test_pebble.py::TestClient::test_replan_services test/test_pebble.py::TestClient::test_replan_services_async test/test_pebble.py::TestClient::test_restart_services test/test_pebble.py::TestClient::test_restart_services_async test/test_pebble.py::TestClient::test_send_signal_name test/test_pebble.py::TestClient::test_send_signal_number test/test_pebble.py::TestClient::test_send_signal_type_error test/test_pebble.py::TestClient::test_start_services test/test_pebble.py::TestClient::test_start_services_async test/test_pebble.py::TestClient::test_stop_services test/test_pebble.py::TestClient::test_stop_services_async test/test_pebble.py::TestClient::test_wait_change_error test/test_pebble.py::TestClient::test_wait_change_success test/test_pebble.py::TestClient::test_wait_change_success_multiple_calls test/test_pebble.py::TestClient::test_wait_change_success_polled test/test_pebble.py::TestClient::test_wait_change_success_polled_timeout_none test/test_pebble.py::TestClient::test_wait_change_success_timeout_none test/test_pebble.py::TestClient::test_wait_change_timeout test/test_pebble.py::TestClient::test_wait_change_timeout_polled test/test_pebble.py::TestSocketClient::test_real_client test/test_pebble.py::TestSocketClient::test_socket_not_found test/test_pebble.py::TestExecError::test_init test/test_pebble.py::TestExecError::test_str test/test_pebble.py::TestExecError::test_str_truncated test/test_pebble.py::TestExec::test_arg_errors test/test_pebble.py::TestExec::test_connect_websocket_error test/test_pebble.py::TestExec::test_no_wait_call test/test_pebble.py::TestExec::test_send_signal test/test_pebble.py::TestExec::test_wait_change_error test/test_pebble.py::TestExec::test_wait_exit_nonzero test/test_pebble.py::TestExec::test_wait_exit_zero test/test_pebble.py::TestExec::test_wait_file_io test/test_pebble.py::TestExec::test_wait_other_args test/test_pebble.py::TestExec::test_wait_output test/test_pebble.py::TestExec::test_wait_output_bad_command test/test_pebble.py::TestExec::test_wait_output_bytes test/test_pebble.py::TestExec::test_wait_output_combine_stderr test/test_pebble.py::TestExec::test_wait_output_exit_nonzero test/test_pebble.py::TestExec::test_wait_output_exit_nonzero_combine_stderr test/test_pebble.py::TestExec::test_wait_output_send_stdin test/test_pebble.py::TestExec::test_wait_output_send_stdin_bytes test/test_pebble.py::TestExec::test_wait_passed_output test/test_pebble.py::TestExec::test_wait_passed_output_bad_command test/test_pebble.py::TestExec::test_wait_passed_output_bytes test/test_pebble.py::TestExec::test_wait_passed_output_combine_stderr test/test_pebble.py::TestExec::test_wait_returned_io test/test_pebble.py::TestExec::test_wait_returned_io_bytes test/test_pebble.py::TestExec::test_wait_timeout test/test_pebble.py::TestExec::test_websocket_recv_raises test/test_pebble.py::TestExec::test_websocket_send_raises