diff --git a/ops/pebble.py b/ops/pebble.py
index 3654185..80ce8f6 100644
--- a/ops/pebble.py
+++ b/ops/pebble.py
@@ -1623,6 +1623,10 @@ class Client:
                 message = f'{type(e2).__name__} - {e2}'
             raise APIError(body, code, status, message)
         except urllib.error.URLError as e:
+            if e.args and isinstance(e.args[0], FileNotFoundError):
+                raise ConnectionError(
+                    f"Could not connect to Pebble: socket not found at {self.socket_path!r} "
+                    "(container restarted?)") from None
             raise ConnectionError(e.reason)
 
         return response

diff --git a/test/test_pebble.py b/test/test_pebble.py
index 47e7388..af4937d 100644
--- a/test/test_pebble.py
+++ b/test/test_pebble.py
@@ -2579,6 +2579,7 @@ class TestSocketClient(unittest.TestCase):
         with self.assertRaises(pebble.ConnectionError) as cm:
             client.get_system_info()
         self.assertIsInstance(cm.exception, pebble.Error)
+        self.assertIn("Could not connect to Pebble", str(cm.exception))
 
     def test_real_client(self):
         shutdown, socket_path = fake_pebble.start_server()

Better Error Handling if the pebble socket goes missing
On a Microk8s cloud there were some issues causing containers to get restarted.  Because containers were getting rescheduled, it ended up that during the time that a charm hook was firing, it ultimately failed to stay connected to pebble. The error message that you end up getting is "NoSuchFile" which is hard to interpret as "pebble went away".
The specific traceback was:
```
Traceback (most recent call last):
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/pebble.py", line 1331, in _request_raw
    response = self.opener.open(request, timeout=self.timeout)
  File "/usr/lib/python3.8/urllib/request.py", line 525, in open
    response = self._open(req, data)
  File "/usr/lib/python3.8/urllib/request.py", line 542, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/pebble.py", line 84, in http_open
    return self.do_open(_UnixSocketConnection, req, socket_path=self.socket_path)
  File "/usr/lib/python3.8/urllib/request.py", line 1357, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 2] No such file or directory>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./src/charm.py", line 777, in <module>
    main(PostgresqlOperatorCharm, use_juju_for_storage=True)
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/main.py", line 429, in main
    framework.reemit()
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/framework.py", line 794, in reemit
    self._reemit()
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/framework.py", line 857, in _reemit
    custom_handler(event)
  File "./src/charm.py", line 381, in _on_postgresql_pebble_ready
    current_layer = container.get_plan()
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/model.py", line 1367, in get_plan
    return self._pebble.get_plan()
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/pebble.py", line 1615, in get_plan
    resp = self._request('GET', '/v1/plan', {'format': 'yaml'})
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/pebble.py", line 1297, in _request
    response = self._request_raw(method, path, query, headers, data)
  File "/var/lib/juju/agents/unit-postgresql-k8s-0/charm/venv/ops/pebble.py", line 1344, in _request_raw
    raise ConnectionError(e.reason)
ops.pebble.ConnectionError: [Errno 2] No such file or directory
```

There is a 'pebble.ConnectionError' in there, but the feedback from others is that it really wasn't clear why this was failing.

It would be nice if we could more clearly articulate this as something like "could not connect to pebble, socket not found at /...". Or even better if we could tell that we *did* have a connection earlier in the process, and could report that we *lost* the connection to pebble.

test/test_pebble.py::TestSocketClient::test_socket_not_found
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_equality 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_change_str 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::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_no_stdout 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