Error handling for PubNub Chat Components for React
Migrate to Chat SDK
PubNub will stop supporting Chat Components on January 1, 2025 but you are welcome to contribute. Learn how to migrate to the Chat SDK here.
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 linesErrors 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>;
}