awslabs / aws-crt-nodejs

NodeJS bindings for the AWS Common Runtime.
Apache License 2.0
37 stars 24 forks source link

Improve error messages that are returned when an exception is thrown while attempting to subscribe in JS #460

Closed ayomikvn closed 1 year ago

ayomikvn commented 1 year ago

Describe the feature

Description

When using the subscribe() method in a JavaScript application (ReactJS), if the method gets a QoS parameter that is of type string, it throws an exception with an empty error message. This makes it difficult to debug the issue.

For instance:

The HTML radio input always returns a value of type string, regardless of what value type you specify. This is the react component I used:

const QualityOfService = (props) => {
    return (
        <RadioGroupField label="Quality of Service" name={props.name} onChange={props.onChange} defaultValue={mqtt.QoS.AtMostOnce}>
            <Radio value={mqtt.QoS.AtMostOnce}>Quality of Service 0 - Message will be delivered at most once</Radio>
            <Radio value={mqtt.QoS.AtLeastOnce}>Quality of Service 1 - Message will be delivered at least once</Radio>
        </RadioGroupField>
    );
}

Hence, the code below returns an error with message, There is something wrong with the subscription: {} and there is no subscribe event seen in AWS IoT Core's CloudWatch logs:

// Trigger topic subscription
    const subscribeHandler = (event) => {
        event.preventDefault();

        let temporarySubscriptionObject = { 'topic': '', 'qosLevel': null };
        temporarySubscriptionObject.topic = topic;
        temporarySubscriptionObject.qosLevel = qosLevel;

        setSubscriptionObjects(prevSubscriptions => [...prevSubscriptions, temporarySubscriptionObject]);
    };

console.log(`Subscribing to ${subscriptionObject.topic} with QoS type ${typeof subscriptionObject.qosLevel} ...`);
async function beginSubscription(connection) {
                try {
                    let returnedSubscription = await connection.subscribe(
                        subscriptionObject.topic,
                        subscriptionObject.qosLevel,
                        (topic, payload, dup, qos, retain) => {
                            const decoder = new TextDecoder("utf8");
                            let message = decoder.decode(new Uint8Array(payload));

                            console.log(`Message received: topic=${topic} message=${message}`);

                            setMessageobjects(prevMessageObjects => [...prevMessageObjects, { 'topic': topic, 'message': message }]);
                        })

                    console.log(`Checking that the subscribe is working: ${JSON.stringify(returnedSubscription)}`);
                } catch (error) {
                    console.log(`There is something wrong with the subscription: ${JSON.stringify(error)}`);
                }

            }

Use Case

I need this for scenarios where I'm developing an application in JavaScript, and not TypeScript.

Proposed Solution

Validate type of the QoS value, before subscribing.

Other Information

No response

Acknowledgements

TwistedTwigleg commented 1 year ago

Thank you for making this issue! There was internal discussion on this prior to this issue being made and based on that discussion I made a PR to fix this based on that discussion. The PR directly addresses this issue and was only made thanks to the discussion.

Closing this issue. Thank you so much for letting us know so we could fix this!