LogoLogo
AMPS Python Client 5.3.4
AMPS Python Client 5.3.4
  • Welcome to the AMPS Python Client
    • Before You Start
    • Obtaining and Installing the AMPS Python Client
    • Your First AMPS Program
      • Client Identification
      • Connection Strings for AMPS
      • Connection Parameters for AMPS
      • Providing Credentials to AMPS
    • Subscriptions
      • Content Filtering
        • Changing the Filter on a Subscription
      • Synchronous Message Processing
      • Asynchronous Message Processing
        • Understanding Threading
      • Understanding Message Objects
      • Regular Expression Subscriptions
      • Ending Subscriptions
    • Error Handling
      • Exceptions
      • Exception Types
      • Exception Handling and Asynchronous Message Processing
      • Controlling Blocking with Command Timeout
      • Disconnect Handling
        • Using a Heartbeat to Detect Disconnection
        • Managing Disconnection
        • Replacing Disconnect Handling
      • Unexpected Messages
      • Unhandled Exceptions
      • Detecting Write Failures
      • Monitoring Connection State
    • State of the World
      • SOW and Subscribe
      • Setting Batch Size
      • Managing SOW Contents
      • Client Side Conflation
    • Using Queues
      • Backlog and Smart Pipelining
      • Acknowledging Messages
      • Returning a Message to the Queue
      • Manual Acknowledgment
    • Delta Publish and Subscribe
      • Delta Subscribe
      • Delta Publish
    • High Availability
    • AMPS Programming: Working with Commands
    • Utility Classes
    • Advanced Topics
    • Exceptions Reference
    • AMPS Server Documentation
    • API Documentation
Powered by GitBook

Get Help

  • FAQ
  • Legacy Documentation
  • Support / Contact Us

Get AMPS

  • Evaluate
  • Develop

60East Resources

  • Website
  • Privacy Policy

Copyright 2013-2024 60East Technologies, Inc.

On this page
Export as PDF
  1. Welcome to the AMPS Python Client
  2. Error Handling

Unhandled Exceptions

When using the asynchronous interface, exceptions can occur that are not thrown to the user. For example, when an exception occurs in the process of reading subscription data from the AMPS server, the exception occurs on a thread inside of the AMPS Python client. Consider the following example using the asynchronous interface:

class MyApp:
    def on_message_handler(self,message):
        print(message.get_data())

    def wait_to_be_poked(self,client):
        client.subscribe(
            self.on_message_handler,
            "pokes",
            "/Pokee LIKE '%s'" % getpass.getuser(),
            timeout=5000)
        input("Press enter to exit")

In this example, we set up a subscription to wait for messages on the pokes topic, whose Pokee tag begins with our user name. When messages arrive, we print a message out to the console, but otherwise our application waits for a key to be pressed.

Inside of the AMPS client, the client creates a new thread of execution that reads data from the server, and invokes message handlers and disconnect handlers when those events occur. When exceptions occur inside this thread, however, there is no caller for them to be thrown to and by default they are ignored.

In applications that use the asynchronous interface, and where it is important to deal with every issue that occurs in using AMPS, you can set an ExceptionHandler via Client.set_exception_listener() that receives these otherwise unhandled exceptions. Making the modifications shown in the example below, to our previous example, will allow those exceptions to be caught and handled. In this case we are simply printing those caught exceptions out to the console.

In some cases, the AMPS Python client may wrap exceptions of unknown type into an AMPSException. Your application should always include an except block for AMPSException.

If your application will attempt to recover from an exception thrown on the background processing thread, your application should set a flag and attempt recovery on a different thread than the thread that called the exception listener.

At the point that the AMPS client calls the exception listener, it has handled the exception. Your exception listener must not rethrow the exception (or wrap the exception and throw a different exception type).

class MyApp:
    def on_exception(self, e):
        print ("Exception occurred: %s" % str(e))

    def on_message_handler(self,message):
        print (message.get_data())

    def wait_to_be_poked(self, client):
        client.set_exception_listener(self.on_exception)

        # Use the advanced interface to be able to
        # accept input while processing messages.

        client.subscribe(
            self.on_message_handler,
            "pokes",
            "/Pokee LIKE '%s'" % getpass.getuser(),
            timeout=5000)
        input("Press enter to exit")

In this example we have added a call to client.set_exception_listener(), registering a simple function that writes the text of the exception out to the console. If exceptions are thrown in the message handler, those exceptions are written to the console.

AMPS records the stack trace and provides it to the exception handler, if the provided method includes a parameter for the stack trace. The sample below demonstrates one way to do this. (For sample purposes, the message handler always throws an exception.)

import AMPS
import time
import traceback

def handler(message):
    print (message)
    raise RuntimeError("in my handler")

def exception_listener(exception, tb):
    print ("EXCEPTION RECEIVED", exception)
    if tb is not None:
        traceback.print_tb(tb)

client = AMPS.Client("client")

client.set_exception_listener(exception_listener)

client.connect("tcp://localhost:9007/amps/json")

client.logon()
client.subscribe(handler,"topic")
client.publish("topic","data")
time.sleep(1)
client.close()
PreviousUnexpected MessagesNextDetecting Write Failures

Last updated 4 months ago