Search code examples
pythonpython-3.xpyqtpyqt5dbus

PyQt5 create error upon failed dbus request


Using PyQt5's D-Bus, how do I create an error? For example, if someone sends an unknown command in a chat program, I'd like to be able to let the client know something like as follows:

error = QDBusMessage.createError(QDBusError.UnknownProperty, "unknown command")
QDBusConnection.systemBus().send(error)

However, this fails with the message:

*** TypeError: arguments did not match any overloaded call:
  createErrorReply(self, str, str): first argument of unbound method must have type 'QDBusMessage'
  createErrorReply(self, QDBusError): first argument of unbound method must have type 'QDBusMessage'
  createErrorReply(self, QDBusError.ErrorType, str): first argument of unbound method must have type 'QDBusMessage'

I can't make heads no tail of this error, since as far as I can tell I'm using it exactly as described. The first arg must be QDBusMessage, since that's what's before the dot. The second arg is of the right type, being <class 'PyQt5.QtDBus.QDBusError.ErrorType'> as returned by type(QDBusError.UnknownProperty). And the quotes mean it's a string, which is what str is.

I also tried sendErrorReply(), but that doesn't seem to exist in PyQt5. At least, I can't find it - it's not beside systemBus's send(), and it's not found in QDBusMessage.

Neither of the examples in PyQt5's examples/dbus/chat folder emit errors. There is no Python documentation available at http://pyqt.sourceforge.net/Docs/PyQt5/QtDBus.html.


Solution

  • I came across your question when I had the same problem as you, a lack of sendErrorReply in PyQt5.

    Here's how I got it to work in my Bluetooth application:

    @pyqtSlot(QDBusMessage)
        def AuthorizeService(self, message):
            print("rejecting service authorization")
            error = message.createErrorReply(QDBusError.AccessDenied, "Failed")
            self._bus.send(error)
    

    The trick is to create the error reply from the message that was received.