Refactor IPC exceptions handling.
Also fixes an IPC error when qutebrowser was started twice without delay between the invocations.
This commit is contained in:
parent
38d34e1dea
commit
43df32949d
@ -31,6 +31,7 @@ import functools
|
|||||||
import traceback
|
import traceback
|
||||||
import faulthandler
|
import faulthandler
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
||||||
from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon, QCursor, QWindow
|
from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon, QCursor, QWindow
|
||||||
@ -115,12 +116,18 @@ class Application(QApplication):
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
log.init.debug("Starting IPC server...")
|
log.init.debug("Starting IPC server...")
|
||||||
ipc.init()
|
ipc.init()
|
||||||
except ipc.IPCError as e:
|
except ipc.AddressInUseError as e:
|
||||||
text = ('{}\n\nMaybe another instance is running but '
|
# This could be a race condition...
|
||||||
'frozen?'.format(e))
|
log.init.debug("Got AddressInUseError, trying again.")
|
||||||
msgbox = QMessageBox(QMessageBox.Critical, "Error while "
|
time.sleep(500)
|
||||||
"connecting to running instance!", text)
|
sent = ipc.send_to_running_instance(self._args.command)
|
||||||
msgbox.exec_()
|
if sent:
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
ipc.display_error(e)
|
||||||
|
sys.exit(1)
|
||||||
|
except ipc.Error as e:
|
||||||
|
ipc.display_error(e)
|
||||||
# We didn't really initialize much so far, so we just quit hard.
|
# We didn't really initialize much so far, so we just quit hard.
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ import getpass
|
|||||||
import binascii
|
import binascii
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSlot, QObject
|
from PyQt5.QtCore import pyqtSlot, QObject
|
||||||
from PyQt5.QtNetwork import QLocalSocket, QLocalServer
|
from PyQt5.QtNetwork import QLocalSocket, QLocalServer, QAbstractSocket
|
||||||
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
|
|
||||||
from qutebrowser.utils import log, objreg, usertypes
|
from qutebrowser.utils import log, objreg, usertypes
|
||||||
|
|
||||||
@ -36,11 +37,40 @@ WRITE_TIMEOUT = 1000
|
|||||||
READ_TIMEOUT = 5000
|
READ_TIMEOUT = 5000
|
||||||
|
|
||||||
|
|
||||||
class IPCError(Exception):
|
class Error(Exception):
|
||||||
|
|
||||||
"""Exception raised when there was a problem with IPC."""
|
"""Exception raised when there was a problem with IPC."""
|
||||||
|
|
||||||
|
|
||||||
|
class ListenError(Error):
|
||||||
|
|
||||||
|
"""Exception raised when there was a problem with listening to IPC.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
code: The error code.
|
||||||
|
message: The error message.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, server):
|
||||||
|
"""Constructor.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
server: The QLocalServer which has the error set.
|
||||||
|
"""
|
||||||
|
super().__init__()
|
||||||
|
self.code = server.serverError()
|
||||||
|
self.message = server.errorString()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Error while listening to IPC server: {} (error {})".format(
|
||||||
|
self.message, self.code)
|
||||||
|
|
||||||
|
|
||||||
|
class AddressInUseError(ListenError):
|
||||||
|
|
||||||
|
"""Emitted when the server address is already in use."""
|
||||||
|
|
||||||
|
|
||||||
class IPCServer(QObject):
|
class IPCServer(QObject):
|
||||||
|
|
||||||
"""IPC server to which clients connect to.
|
"""IPC server to which clients connect to.
|
||||||
@ -63,9 +93,10 @@ class IPCServer(QObject):
|
|||||||
self._server = QLocalServer(self)
|
self._server = QLocalServer(self)
|
||||||
ok = self._server.listen(SOCKETNAME)
|
ok = self._server.listen(SOCKETNAME)
|
||||||
if not ok:
|
if not ok:
|
||||||
raise IPCError("Error while listening to IPC server: {} "
|
if self._server.serverError() == QAbstractSocket.AddressInUseError:
|
||||||
"(error {})".format(self._server.errorString(),
|
raise AddressInUseError(self._server)
|
||||||
self._server.serverError()))
|
else:
|
||||||
|
raise ListenError(self._server)
|
||||||
self._server.newConnection.connect(self.handle_connection)
|
self._server.newConnection.connect(self.handle_connection)
|
||||||
self._socket = None
|
self._socket = None
|
||||||
|
|
||||||
@ -73,8 +104,7 @@ class IPCServer(QObject):
|
|||||||
"""Remove an existing server."""
|
"""Remove an existing server."""
|
||||||
ok = QLocalServer.removeServer(SOCKETNAME)
|
ok = QLocalServer.removeServer(SOCKETNAME)
|
||||||
if not ok:
|
if not ok:
|
||||||
raise IPCError("Error while removing server {}!".format(
|
raise Error("Error while removing server {}!".format(SOCKETNAME))
|
||||||
SOCKETNAME))
|
|
||||||
|
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def on_error(self, error):
|
def on_error(self, error):
|
||||||
@ -185,13 +215,13 @@ def init():
|
|||||||
|
|
||||||
|
|
||||||
def _socket_error(action, socket):
|
def _socket_error(action, socket):
|
||||||
"""Raise an IPCError based on an action and a QLocalSocket.
|
"""Raise an Error based on an action and a QLocalSocket.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
action: A string like "writing to running instance".
|
action: A string like "writing to running instance".
|
||||||
socket: A QLocalSocket.
|
socket: A QLocalSocket.
|
||||||
"""
|
"""
|
||||||
raise IPCError("Error while {}: {} (error {})".format(
|
raise Error("Error while {}: {} (error {})".format(
|
||||||
action, socket.errorString(), socket.error()))
|
action, socket.errorString(), socket.error()))
|
||||||
|
|
||||||
|
|
||||||
@ -235,3 +265,11 @@ def send_to_running_instance(cmdlist):
|
|||||||
log.ipc.debug("No existing instance present (error {})".format(
|
log.ipc.debug("No existing instance present (error {})".format(
|
||||||
socket.error()))
|
socket.error()))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def display_error(exc):
|
||||||
|
"""Display a message box with an IPC error."""
|
||||||
|
text = '{}\n\nMaybe another instance is running but frozen?'.format(exc)
|
||||||
|
msgbox = QMessageBox(QMessageBox.Critical, "Error while connecting to "
|
||||||
|
"running instance!", text)
|
||||||
|
msgbox.exec_()
|
||||||
|
Loading…
Reference in New Issue
Block a user