Azure/azure-iot-sdk-python

Sync expection into async implementation

Cavalletta98 opened this issue · 4 comments

Hi, i'm developing an async code to retrieve the twin desired patch. if i try to access to a field that is not present in the twin, i get this expection
Exception caught in background thread. Unable to handle. ['azure.iot.device.iothub.sync_handler_manager.HandlerManagerException: HANDLER (CLIENT_EVENT)

I want to know if it is a bug that a sync expection is raised and how to handle it

Thanks

@Cavalletta98

This is expected - it's just an artifact of where the exception is defined.

As far as how to handle it, background exceptions can be accessed via the on_background_exception handler property on the client. Set a function that takes one argument (the exception object), and it will be returned through that callback/handler.

Ho @cartertinney thanks for the response. Can you please provide and example code?

@Cavalletta98

Here is a modified receive_message sample. It's for async, but the principle applies whichever client you are using - you just define a handler and set it, similar to how receiving a message works.

import os
import asyncio
from azure.iot.device.aio import IoTHubDeviceClient


async def main():
    # The connection string for a device should never be stored in code. For the sake of simplicity we're using an environment variable here.
    conn_str = os.getenv("IOTHUB_DEVICE_CONNECTION_STRING")
    # The client object is used to interact with your Azure IoT hub.
    device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)

    # connect the client.
    await device_client.connect()

    # define behavior for receiving a message
    # NOTE: this could be a function or a coroutine
    def message_received_handler(message):
        print("the data in the message received was ")
        print(message.data)
        print("custom properties are")
        print(message.custom_properties)
        print("content Type: {0}".format(message.content_type))
        print("")

    def background_exception_handler(e):
        print("Exception raised in background thread: {}".format(e))

    # set the message received handler on the client
    device_client.on_message_received = message_received_handler
    device_client.on_background_exception = background_exception_handler

    # define behavior for halting the application
    def stdin_listener():
        while True:
            selection = input("Press Q to quit\n")
            if selection == "Q" or selection == "q":
                print("Quitting...")
                break

    # Run the stdin listener in the event loop
    loop = asyncio.get_running_loop()
    user_finished = loop.run_in_executor(None, stdin_listener)

    # Wait for user to indicate they are done listening for messages
    await user_finished

    # Finally, shut down the client
    await device_client.shutdown()


if __name__ == "__main__":
    asyncio.run(main())

Hi @cartertinney , we implemented into a code that handle the patch of the twin but it doesn't work. Do know where is the possibile problem? we testd in a module that does not manage the twin patch and it works