Catching Server-side Rendering Errors in React JSS Apps

It was quite common for Sitecore MVC implementation to add logic around renderings that will catch unexpected exceptions in them and save your page from complete collapse. Such logic hides your component from end users and might only put something in HTML comments, while during preview or editing experience it will give some visual indication of an error and its details.
Such functionality can also be very useful for React JSS applications, but it is not that simple especially on for isomorphic apps leveraging SSR (server-side rendering).

Error handling in React will be handled differently on a client and a server side. Let’s start from the first one.

Client-side error handling

In the past, React was not very explicit about the errors and was emitting cryptic errors, but things got better with the introduction of Error Boundaries.
Error Boundaries worked very similarly to the Sitecore approach defined above. They catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed.
It worth mentioning that Error Boundary wrapped around component will work with its lifecycle methods and constructors, but will not help you with events handlers and async code, as well as during SSR.

Server-side error handling

By design, React SSR uses supports streaming, which means that a server starts sending processed elements of your component tree through the wire while the rest is still generating HTML.
That makes it impossible for Error Boundaries to hide part of a components tree where the exception happened.

The only place where you can catch errors on the server is inside a method render(). Obviously, putting try catch in every render() method will be time-consuming and error-prone.

In case you are using Babel to process your code, you can leverage its plugin. The plugin will do the magic for you and wrap the content of all render() methods in try/catch, but I prefer to use TypeScript in my projects as it allows to catch many compile-time errors before the code is pushed anywhere.
Mixing TypeScript processing with Babel processing is possible but not the most fun process, so I’ve ended up creating extending a PureComponent class with an error handling logic, which you can see below.

import * as React from 'react';
import * as Models from './models';
export class SafePureComponent<P, S extends Models.SafePureComponentState> extends React.PureComponent<P, S> {
private hasError: boolean = false;
constructor(props: P, context?: any) {
super(props, context);
public componentDidMount() {
this.setState({ hasError: this.hasError });
public render() {
// componentDidCatch doesn't work in React 16's renderToString
// Due to streaming nature of renderToString in React 16, need to wrap each render method in try/catch
try {
// Using error boundaries for client-side rendering
if (this.state && this.state.hasError) {
return this.renderErrorView();
return this.safeRender();
} catch (error) {
// this allows to differentiate server vs client rendering
if (typeof window !== 'undefined') {
// used to avoid side-effects via setState()
this.hasError = true;
console.error('Error inside', this.getComponentName(), 'is', error);
return this.renderErrorView();
// this method should be overridden in nested classes
protected safeRender(): React.ReactNode {
return (
<span dangerouslySetInnerHTML={{ __html: `<!– Component ${this.getComponentName()} is not implemented. –>` }} />
protected renderErrorView() {
return (
__html: `<!– Error inside ${this.getComponentName()}. For more info, please, check the console."–>`,
protected getComponentName() {
return !! ? : 'component';
view raw index.jsx hosted with ❤ by GitHub
export interface SafePureComponentState {
hasError?: boolean;
view raw model.js hosted with ❤ by GitHub

Comments above will give you a pretty good understanding of what is happening. Here are some additional details.

As we do not have an option of virtual methods calling base methods, we need to have safeRender() that will be used in all derived components. In this method, you will write presentation logic. Render() method is implemented in this class and provides handling.

Before calling safeRender() in try/catch section we are checking if a component has an error in its state. This is applicable only for the client as SSR will not call componentDidMount() method. This will ensure that you won’t go in cycles there.

Catch{} section checking window object to understand if we are in a browser and running additional logging into a console. Both SSR and client rendering, leaving HTML comment in markup via renderErrorView(), so that you will be able to catch collapsed components. You can override this method and add your custom logic there, e.g. check if you are in Experience editor or on the live site.

Obviously, all components on the site should be inherited from this one to make it work.

As usual, follow me on twitter @true_shoorik 😉

Catching Server-side Rendering Errors in React JSS Apps

One thought on “Catching Server-side Rendering Errors in React JSS Apps

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s