Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWS IoT MQTT Client Error Handling Improvement Needed #543

Open
GuilhermeScherner opened this issue Feb 3, 2025 · 2 comments
Open

AWS IoT MQTT Client Error Handling Improvement Needed #543

GuilhermeScherner opened this issue Feb 3, 2025 · 2 comments
Labels
feature-request A feature should be added or improved. p3 This is a minor priority issue

Comments

@GuilhermeScherner
Copy link

Describe the bug

The MQTT client error handler in our application is not providing sufficient error type information when connection issues occur, particularly with WebSocket connections and credential expiration. This makes it difficult to implement proper error handling and recovery strategies.

const currentCredentials = await Auth.currentCredentials();
const clientId = guffo-${Math.floor(Math.random() * 100000 + 1)}-${Date.now()};

  const client = new mqtt.MqttClient();
  const config = iot.AwsIotMqttConnectionConfigBuilder.new_builder_for_websocket()
    .with_clean_session(true)
    .with_client_id(clientId)
    .with_endpoint(process.env.REACT_APP_AWS_ENDPOINT || '')
    .with_credentials(
      process.env.REACT_APP_AWS_COGNITO_REGION || '',
      currentCredentials.accessKeyId,
      currentCredentials.secretAccessKey,
      currentCredentials.sessionToken,
    )
    .with_keep_alive_seconds(60)
    .build();

  const mqttClient = client.new_connection(config);

So when I try to catch errors with this code

  mqttClient.on('error', async (error) => {
      console.log('Connection error:', error);
      if (navigator.onLine) await resetConnection();
    });

    if (!notSubscribeRef.current) {
      mqttClient.on('interrupt', async () => {
        console.log('Connection interrupted');
        if (navigator.onLine) await resetConnection();
      });

      mqttClient.on('disconnect', async () => {
        console.log('Disconnected from MQTT');
        if (navigator.onLine) await resetConnection();
      });

      mqttClient.on('connection_failure', async () => {
        console.log('Connection failure');
        setTimeout(resetConnection, RECONNECT_DELAY);
      });
    }

Expected Behavior

The error handler should:

  1. Provide detailed error type information to distinguish between different failure scenarios
  2. Include specific error codes or types for common failures like:
    • Credential expiration
    • WebSocket connection failures
    • Network connectivity issues
    • Authentication failures
  3. Allow implementing specific handling strategies based on error types

Current Behavior

Currently, when connection issues occur:

  1. The error event handler receives a generic error object without specific error type information
  2. We cannot distinguish between different types of failures (credential expiration, network issues, etc.)
  3. The error handler triggers a generic reconnection attempt without being able to handle specific cases differently
  4. No specific error information is provided when credentials expire or when WebSocket connection fails

Reproduction Steps

Initiate an MQTT websocket connection using cognito and wait for the connection to close on error.

Possible Solution

No response

Additional Information/Context

No response

SDK version used

SDK Version: aws-iot-device-sdk-js-v2 1.17.0

Environment details (OS name and version, etc.)

Platform: Browser (React application)

@GuilhermeScherner GuilhermeScherner added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Feb 3, 2025
@bretambrose
Copy link
Contributor

To the best of my knowledge, much of what you're asking for isn't possible and/or would not be a good idea to attempt (for example, trying to parse the underlying errors for reasons).

The browser SDK is a thin wrapper (adding websocket signing) around mqtt-js, using browser websocket APIs for connection establishment. The SDK does not have access to most of the information you're asking for; all we can do is relay the exception from the layer beneath. For example, browsers do not provide any way to query the http response (http code or response body) to the websocket upgrade, which means we have almost no ability to analyze why a connection attempt failed.

A few suggestions:

  1. The samples show a hacky-but-simple way to setup automatic credentials refresh with cognito. Using session credentials as if they were static and trying to tease out expiration errors is additional unnecessary complexity and not at all advised.
  2. We recommend using the MQTT5 client and not the 311 client. 5 is a better protocol (although the error handling improvements don't kick in until a connection is established) and we've removed the horrible only-reconnect-if-the-first-connection-attempt-succeeded behavior of the 311 client, which has been a point of regret for 5 years running now.
  3. The client's error event is intended for informational purposes. We recommend using particular lifecycle events (connection succeeded, connection failed, etc...)

If you have detailed suggestions about how to give better error information (maybe there are places in the codebase where we drop useful information), we'd be happy to look into them, but the current philosophy is "all we can do is report what the underlying layer told us."

@bretambrose bretambrose added feature-request A feature should be added or improved. p3 This is a minor priority issue and removed bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Feb 3, 2025
@GuilhermeScherner
Copy link
Author

GuilhermeScherner commented Feb 3, 2025

I'm encountering an issue when trying to connect to AWS IoT via WebSocket. The connection attempt fails with the following error message:
WebSocket connection to 'wss://...-ats.iot.eu-west-1.amazonaws.com/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA3FKJWLVG6LQ5AUEP%2F20250203%2Feu-west-1%2Fiotdevicegateway%2Faws4_request&X-Amz-Date=...&X-Amz-SignedHeaders=...&X-Amz-Signature=...&X-Amz-Security-Token=...' failed: Error during WebSocket handshake: Unexpected response code: 403

Error occurs in stream.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. p3 This is a minor priority issue
Projects
None yet
Development

No branches or pull requests

2 participants