Error handling for PubNub Chat Components for React

Passing wrong types of data into the components, unavailability or a limited network connection, and unexpected behaviors are all examples of what might cause exceptions to be thrown from inside of the components code.

The results of those problems might vary, starting with some interactions being blocked and ending with your whole application crashing. That is why it is important to be able to add some form of error handling to your usage of components.

Error callback

The fundamental way of capturing and handling errors coming from the components is by using the onError property of the Chat provider component and passing it to a custom callback function. This function will be called each time a JavaScript exception is raised within the components code with the actual error passed in as an argument.

You can use the custom error callback for:

  • Debugging
  • Logging
  • Displaying notifications to the end user
  • Rerendering

An example of simple logging behavior can be as follows:

function ErrorChat() {
const [currentChannel, setCurrentChannel] = React.useState("test-channel");

const onError = (error: Error) => {
yourLogger.log(error.message, error.status);
};

return (
<Chat {...{ currentChannel, onError }}>
<MessageList />
<MessageInput />
</Chat>
);
}

Automatic retries

In addition to the error callback, there is an automatic retry behavior built in for some of the component functionalities (currently fetching messages history). It is disabled by default, but can be easily configured for environments in which network connection is not too stable, and you don't want the connections to fail immediately.

To enable the retry behavior you must configure the retryOptions property on the Chat provider:

  • Provide the maximum number of retries.
  • Provide the timeout between requests.
  • Set a factor number for exponential timeout lengths (1 results in linear timeouts).

In the example below, if the network connection is down, the components will try to fetch message history up to 5 times, with timeout between each request starting from 1 second, to 2, 4, and ending on 8 seconds before the last call.

function RetryChat() {
const [currentChannel, setCurrentChannel] = React.useState("test-channel");

const retryOptions = {
maxRetries: 5,
timeout: 1000,
exponentialFactor: 2,
};

return (
<Chat {...{ currentChannel, retryOptions }}>
<MessageList />
<MessageInput />
</Chat>
);
show all 16 lines

Errors in custom hooks

Custom hooks have their own way of handling errors. Every custom hook exposes the most recent error it ran into as the last element of its output array.

You can easily detect changes to the variable using the standard React useEffect hook and put your custom handling logic there, or use the error to directly influence the UI.

function ErrorHook() {
const [presenceData, refetch, total, error] = usePresence({ channels: ["test-channel"] });

React.useEffect(() => {
if (error) yourLogger.log(error.message, error.status);
}, [error]);

return <p>{error ? `Presence error: ${error.message}` : `Currently chatting: ${total}`}</p>;
}