Handeling Errors thrown by PythonKit or better way to interact with Docker

Got a MacOS app I am working on and I need to know if Docker is running or not and start it if it is not. Given I didn't see any docker-client packages for Swift I was going to use PythonKit to interact with Docker.

Doing this and everything is fine, as long as docker is already running. If you try to access docker via pythonkit when docker is not running PythonKit throws an exception but trying to catch it via Swift hasn't worked for me.

Example:

    do {
        let client = try? dckr.from_env()
    }
    catch {
        print("docker still not ready")
    }

Result:

Fatal error: 'try!' expression unexpectedly raised an error: Python exception: Error while fetching server API version: ('Connection aborted.', ConnectionRefusedError(61, 'Connection refused'))

I imagine it would be a lot of hassle to check for errors every time you do anything with PythonKit, which is why it crashes on exceptions by default.

However There's a throwing property on PythonObject which makes the calls and properties throwing

What happens if you write let client = try dckr.throwing.from_env() ?

Value of type 'ThrowingPythonObject' has no member 'from_env'

Huh. It seems they didn't add @dynamicCallable to ThrowingPythonObject because "the syntax is unintuitive", but didn't change the method names. Oh well...

You will have to manually call the necessary method:

let client = try dckr.from_env.throwing.dynamicallyCall(withArguments: [])
2 Likes