Error parsing the response to json

Are you seeing an error that Yoast SEO couldn't complete the optimization of your SEO data? See the most common causes for this error.

As of Yoast SEO 20.0, the settings interface inside our plugins has received a major overhaul. Please update to the latest version of Yoast SEO if your plugin does not look like the screenshots you encounter in our Help center.

To optimize your websites’ SEO data, our plugin keeps a list of relevant data on your site that we can quickly access when needed. We dubbed this data the “indexables“.

Did you know that the indexables use the data they gather about your site to help you optimize it better? Check out the SEO workouts and learn how you can use the indexables technology to keep your site easy to navigate and your content easy to find!

Normally, data gets added to the indexables as soon as you create or update a post. But, when you newly install our plugin, or when some data doesn’t get indexed for some reason, we include the option to kickstart the creation of indexables with the SEO data optimization feature.If this process fails, you’ll get an error saying: “Oops, something has gone wrong and we couldn’t complete the optimization of your SEO data.” This article will describe the most common causes for this error that we see in our support inbox.

Table of contents

  • Why did I get an error for the SEO data optimization?
  • Specific error messages
    • Error parsing the response to JSON
  • Specific status codes
    • Status code 301 / 302
    • Status code 401 / 403
    • Status code 500 through 503 and 504
  • Known cases that will give an SEO data optimization error
    • Case 1: Web Application Firewalls (WAF) blocking (part of) the endpoint
  • Need additional help?

Why did I get an error for the SEO data optimization?

Kickstarting the creation of our indexables can be a taxing process. The larger the site, the longer this process may take. Due to the nature of this process, there are, unfortunately, some ways in which this process may fail. When this happens, for the longest time, we have shown a default error message. Unfortunately, this didn’t help you or our support team to get to the problem. Starting with Yoast 16.9, we now include a technical summary with the error message that may help you figure out what went wrong.

Error message saying: "Oops something has gone wrong and we couldn't complete the optimization of your SEO data." Below the message it shows collapsible headers with error details.

The new “Oops, something has gone wrong” error message

Specific error messages

There may be a specific error message related to SEO data optimization, like the one described below.

Error parsing the response to JSON

Note: having debugging enabled on your website may be the most likely cause of this message. Because debugging will cause any unrelated / less important notices and warnings to interfere with our communication with the website. Please see this WordPress article to learn more about WordPress debugging.

This error most likely means that your website had problems while trying to fulfill the request. When you open op the response in the message, you should find the information that your server sent in response to our request. You can use this information to determine what went wrong.

Specific status codes

You may also get a status code in your error message. What does that code mean?

An error message with the status code 401.

A specific message with status code 401

Status code 301 / 302

301 and 302 are status codes that indicate that a request is being redirected somewhere else. Something in your site redirects this request away from the WordPress API endpoint where we need to be. See if disabling any redirection plugins fixes this, or maybe your web server handles this.

Status code 401 / 403

These status codes deal with requests that are blocked or unauthorized. This means that something in or in front of your website is blocking our requests to the WordPress API. We see that some Web Application FireWalls utilize some rules that may block some of these requests. This status code will also show up if you’ve completely disabled the WordPress API.

Status code 500 through 503 and 504

These status codes indicate that something went wrong within your website while processing our optimization. You should be able to get more information from your websites’ PHP error logs. 504 indicates a timeout. This may indicate there’s an endless loop happening or a lot of data is being processed, which can’t finish before your server terminates the process.

Known cases that will give an SEO data optimization error

Whenever we have investigated an error with a cause that happens to multiple users, we will write a summary in this section to help you determine the next steps to take.

Case 1: Web Application Firewalls (WAF) blocking (part of) the endpoint

We have seen users unable to use the SEO optimization tool because of a WAF blocking (part of) the REST requests that our plugin needs to do. You will see the status code of 401 / 403 with a message that you can’t use that endpoint. One specific WAF that blocks part of our requests that we know of is Comodo. So if you experience these issues and use that WAF, you can check if the issue is resolved when (temporarily) disabling the WAF.

Need additional help?

If you could not find the cause of the error with this article, you can always enlist the help of others. Are you are a Premium customer? Then you can contact our support team. If you are a free user, you can ask your question on the free support forums. Whichever method you use, always provide as many details as possible, including the error details.

Related articles

Пишу серверо-клиентское приложение, запросы/ответы идут в JSON (люблю с ним работать :) ) , для парсинга ответа использую библиотеку Newtonsoft.Json так вот, например ответ сервера:

{
	"status": true,
	"location": "https://ru.wargaming.net/id/openid/?openid.assoc_handle=%7BHMAC-SHA1%7D%7B53c3b656%7D%7BdbdXfQ%3D%3D%7D&openid.ax.if_available=ext0%2Cext1%2Cext2&openid.ax.mode=fetch_request&openid.ax.type.ext0=http%3A%2F%2Faxschema.openid.wargaming.net%2Fspa%2Fid&openid.ax.type.ext1=http%3A%2F%2Faxschema.org%2FnamePerson%2Ffriendly&openid.ax.type.ext2=http%3A%2F%2Faxschema.openid.wargaming.net%2Fidentity%2Fsso%2Fnotifications%2Fdisable&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.realm=https%3A%2F%2Fapi.worldoftanks.ru%2F&openid.return_to=https%3A%2F%2Fapi.worldoftanks.ru%2Fid%2Fcomplete%2F%3Fredirect_uri%3Dhttps%253A%252F%252Fapi.worldoftanks.ru%252Fwot%252Fblank%252F%26application_id%3D0775c3d2e437b4d3a2e386036571e297%26expires_at%3D1407221921%26janrain_nonce%3D2014-07-22T06%253A58%253A41ZepFnu1"}d/openid/?openid.assoc_handle=%7BHMAC-SHA1%7D%7B53c3b656%7D%7BdbdXfQ%3D%3D%7D&openid.ax.if_available=ext0%2Cext1%2Cext2&openid.ax.mode=fetch_request&openid.ax.type.ext0=http%3A%2F%2Faxschema.openid.wargaming.net%2Fspa%2Fid&openid.ax.type.ext1=http%3A%2F%2Faxschema.org%2FnamePerson%2Ffriendly&openid.ax.type.ext2=http%3A%2F%2Faxschema.openid.wargaming.net%2Fidentity%2Fsso%2Fnotifications%2Fdisable&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.realm=https%3A%2F%2Fapi.worldoftanks.ru%2F&openid.return_to=https%3A%2F%2Fapi.worldoftanks.ru%2Fid%2Fcomplete%2F%3Fredirect_uri%3Dhttps%253A%252F%252Fapi.worldoftanks.ru%252Fwot%252Fblank%252F%26application_id%3D0775c3d2e437b4d3a2e386036571e297%26expires_at%3D1407221921%26janrain_nonce%3D2014-07-22T06%253A58%253A41ZepFnu1"}d/openid/?openid.assoc_handle=%7BHMAC-SHA1%7D%7B53c3b656%7D%7BdbdXfQ%3D%3D%7D&openid.ax.if_available=ext0%2Cext1%2Cext2&openid.ax.mode=fetch_request&openid.ax.type.ext0=http%3A%2F%2Faxschema.openid.wargaming.net%2Fspa%2Fid&openid.ax.type.ext1=http%3A%2F%2Faxschema.org%2FnamePerson%2Ffriendly&openid.ax.type.ext2=http%3A%2F%2Faxschema.openid.wargaming.net%2Fidentity%2Fsso%2Fnotifications%2Fdisable&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.realm=https%3A%2F%2Fapi.worldoftanks.ru%2F&openid.return_to=https%3A%2F%2Fapi.worldoftanks.ru%2Fid%2Fcomplete%2F%3Fredirect_uri%3Dhttps%253A%252F%252Fapi.worldoftanks.ru%252Fwot%252Fblank%252F%26application_id%3D0775c3d2e437b4d3a2e386036571e297%26expires_at%3D1407221921%2"
}

Для удобства чтения отформатировал.

Так вот, при парсинге JObject’ом (функция JObject.Parse(json)) у меня вылетает исключение:

Необработанное исключение типа "Newtonsoft.Json.JsonReaderException" произошло в Newtonsoft.Json.dll

Дополнительные сведения: Additional text encountered after finished reading JSON content: . Path '', line 1, position 1175.

Причем такое происходит в любых ответах сервера (содержимое которых сильно отличается), изменяется только позиция и «<какой-то символ>.Path».

В чем проблема? Я уже всячески обрабатывал строку как на сервере так и на клиенте, толку 0.
Причем странность: Ту-же строку (прямо из клиента выводом перед парсингом брал) например Notepad++ с плагином JSON Viewer спокойно парсит.

P.s. И да, на сервере JSON строка собирается тем-же JObject’ом.

UPD. Я покопался дебаггером, и обнаружил:
86c44ccec730483988606175bae34b02.png
Откуда ответ забивается «»?

The most common reason for this error is attempting JSON to parse an HTML or XML response. The HTML and XML documents start with <, and JSON identifies it as an unparsable string. It is also possible that you are requesting an api that you don’t have permission to access. In that case, you expect a JSON, but the server returns a permission denial HTML.

This article demonstrates several JSON parsing errors with code examples.

Reason for Unexpected token < in JSON error

Listed below is a simple express.js route that generates an HTML response. It can be any api endpoint. The api generates the HTML response <p>This is an HTML response</p>.

router.post("/user/create/html", (request, response) => {
    const reply = "<p>This is an HTML response</p>"
    response.set('Content-Type', 'text/html');
    response.send(reply);
});

Now let’s find out what happens when we try to parse this response with the JSON parser. The code makes a post request to the endpoint that produces an HTML response. Then it tries to JSON parse the response.

const serverHtmlResponse = await axios.post('/user/create/html')
console.log(serverHtmlResponse.headers["content-type"])
console.log(serverHtmlResponse.data)
console.log(typeof serverHtmlResponse.data)
const htmlResponse = JSON.parse(serverHtmlResponse.data)
Unexpected token < in JSON error
Figure 1 : Unexpected token < in JSON error

Note that the endpoint’s response type is text/html and the content is <p>This is an HTML response</p>. The content is not parsable. Thats the reason you see the first character of the content < in the error message.

Reason for Unexpected token o in JSON at position 1

That error happens when we attempt to JSON parse an object.
The below express.js route produces a JSON object as the response.

router.post("/user/create/json", (request, response) => {
   const reply = "This is a JSON object response"
   response.json({response:reply});
});

The response of this endpoint is {response: ‘This is a JSON object response’}. That is not a JSON string. It is an object. The console.log(typeof serverJsonResponse.data) proves the api response is an object.

const serverJsonResponse = await axios.post('/user/create/json')
console.log(serverJsonResponse.headers["content-type"])
console.log(typeof serverJsonResponse.data)
console.log(serverJsonResponse.data)
const jsonResponse = JSON.parse(serverJsonResponse.data)
 Unexpected token o in JSON at position 1
Figure 2 : Unexpected token o in JSON at position 1

Therefore, what happens here is JSON.parse(«[object Object]»)
and JSON complains about the character «o» it encountered first.

How to parse a JSON string correctly?

The JSON.parse() method accepts a string that correctly represents a JSON object. In other words, a string that is parsable into a JSON object.
Below is an express route that produces a JSON string like {«response»:»This is a JSON string response»}.

router.post("/user/create/jsonstring", (request, response) => {
   const reply = `{"response":"This is a JSON string response"}`
   response.json(reply)
});

The response is application/json, and the type is string. This type of response is parsable with JSON parser as long as the response string can represent a valid object.

const serverResponse = await axios.post('/user/create/jsonstring')
console.log(serverResponse.headers["content-type"])
console.log(typeof serverResponse.data)
console.log(serverResponse.data)
const jsonStringResponse = JSON.parse(serverResponse.data)

Introduction

A common issue that I see when working with front-end JavaScript heavy apps is the dreaded “SyntaxError Unexpected Token in JSON” error! Now this error can be of the form:

SyntaxError: Unexpected token < in JSON at position 0

SyntaxError: Unexpected end of JSON input

syntaxerror: unexpected token '<', "<!doctype "... is not valid json

The error “SyntaxError Unexpected Token in JSON” appears when you try to parse content (for example — data from a database, api, etc), but the content itself is not JSON (could be XML, HTML, CSV) or invalid JSON containing unescaped characters, missing commas and brackets.

There are a few things you can try to fix this error:

  1. Check that the content you are trying to parse is JSON format and not HTML or XML

  2. Verify that there are no missing or extra commas.

  3. Make sure to check for unescaped special characters.

  4. Check for mismatched brackets or quotes.

  5. Make sure the JSON is valid. You can use a tool like JSONLint to validate your JSON and check for any errors.

1. Check that the content you are trying to parse is JSON format and not HTML or XML

A common reason why the error “SyntaxError Unexpected Token in JSON” comes up is that we are trying to parse content that is not even JSON.

Consider the following front-end JavaScript code:

  

fetch('https://localhost:3000/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
    // Use the data here
  })

In the above example, the fetch() function is being used to retrieve data from a API that returns JSON format — in this case https://localhost:3000/data.

The fetch() function then returns a promise, and when that promise resolves, we handle that with the response.json() method. This just takes our JSON response and converts it to a JSON object to be used!

After that we just console.log out the data object

Now for the server-side of things, look on to our Node JS route that returns the JSON /data

  

var http = require('http');

var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'text/html');  Not returning JSON.
    res.end(JSON.stringify({ a: 1 }));
});
app.listen(3000);

We can see that it is setting the Header as text/html. This will give you the error:

syntaxerror: unexpected token '<', "<!doctype "... is not valid json

This is because we are trying to parse the content with JSON.parse() or in our case response.json() and receiving a HTML file!

To fix this, we just need to change the returned header to res.setHeader('Content-Type', 'application/json'):

  

...
var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'application/json'); ✔️ Returning JSON.
    res.end(JSON.stringify({ a: 1 }));
});
...

Whats Content-Type request header anyway?

Pretty much every resource on the internet will need to have a type (similar to how your file system contains file types like images, videos, text, etc).
This is known as a MIME type (Multipurpose Internet Mail Extension)

Browsers need to know what content type a resource is so that it can best handle it. Most modern browsers are becoming good at figuring out which content type a resource is, but its not always 100% correct.

That is why still need to explicitly specify our request header content-type!

syntaxerror: unexpected token ‘<’, “<!doctype “… is not valid json

This error also comes up when your API is returning invalid error pages such as 404/500 HTML pages. Since HTML usually starts with a “less than” tag symbol (<) and JSON is not valid with < tags, it will through this error.

For example, when everything is working find, your node API will happily return JSON. However when it fails with a 500 internal error, it could return a custom HTML error page!
In this case, when you try to do JSON.parse(data) you will get the syntaxerror: unexpected token '<', "<!doctype "... is not valid json.

Additionally, check that you are calling the correct API url. As an example, lets say the API that returns JSON is using the /data route. If you misspelt this, you could be redirected to a 404 HTML page instead!

Tip: Use appropriate error handlers for non-JSON data

If you are using fetch() to retrieve your data, we can add a catch handler to give meaningful error messages to the user:

  

fetch('https://localhost:3000/data')
  .then(response => response.json())
  .then(data => {
    console.log(data);
    // Use the data here
  })
  .catch(error => console.error(error)); /*✔️ Friendly error message for debugging! */

If you are using JSON.parse() we can do this in a try/catch block as follows:

  

try {
    JSON.parse(data);
}
catch (error) {
    console.log('Error parsing JSON:', error, data); /*✔️ Friendly message for debugging ! */
}

JSON objects and arrays should have a comma between each item, except for the last one.

  

{
    "name": "John Smith"
    "age": 30
    "address": {
        "street": "123 Main St"
        "city": "Anytown"
        "state": "USA"
    }
}

This JSON object will throw a “syntaxerror unexpected token” error because there is no comma between “John Smith” and “age”, and also between “Anytown” and “state”.

To fix this, you would add commas as follows:

  

{
    "name": "John Smith",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "USA"
    }
}

By adding commas between each item except for the last one, the JSON object is now in the correct format and should parse without error.

3. Make sure to use double quotes and escape special characters.

JSON strings must be wrapped in double quotes, and any special characters within the string must be properly escaped. Consider the following example:

  

{
    "name": "John Smith",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "USA"
    },
    "message": "It's a lovely day"
}

When we try to parse this with JSON.parse, we will get the error: SyntaxError: Invalid or unexpected token.

The problem is with the following line using a apostrophe:

"message": "It's a lovely day"

  

{
    "name": "John Smith",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "USA"
    },
    "message": "It's a lovely day"
}

As we can see, this will fix our error since we escape the aspostrophe as such:

"message": "It's a lovely day"

4. Check for mismatched brackets or quotes.

Make sure all brackets and quotes are properly closed and match up.

  

{
    "name": "John Smith",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "USA"
    }

In this example, the JSON object is missing a closing curly bracket, which indicates the end of the object. Because of this, it will throw a “syntaxerror unexpected token” error.

To fix this, you would add the missing closing curly bracket as follows:

  

{
    "name": "John Smith",
    "age": 30,
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "USA"
    }
}

If you want to be sure that the JSON is valid, we can try to use the NPM package JSONLint (https://github.com/zaach/jsonlint)

We can install jsonlint with npm as follows:

  1. Open up the terminal
  2. Run NPM install npm install jsonlint -g
  3. We can then validate a file like so: jsonlint myfile.json

Summary

In this article I went over the SyntaxError: Unexpected token < in JSON at position 0 when dealing with parsing JSON with fetch or JSON.parse. This error is mainly due to the JSON not being in correct format or the content that we are trying to parse is not even JSON.

In the case of JSON being invalid, make sure to check for unescaped characters, missing commas, non-matching brackets and quotes.

To be really sure, check the JSON with tools like JSONLint to validate!

In the case of the content you are trying to parse being non-JSON such as HTML, check your API to make sure that error pages return JSON correctly instead of HTML pages.

This guide will help to fix SyntaxError: Unexpected token < in JSON at position 0. This guide also applies to these other common variants of the same error:

  • SyntaxError: The string did not match the expected pattern.

  • SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

  • JSON Parse error: Unrecognized token '<'

Summary

These errors indicate your JavaScript code expected to receive JSON but got something else instead (probably HTML in the form of a server-side error). To fix the issue you need to examine what you got instead of the expected JSON to determine what the problem is.

Details

Usually this error is caused when your server returns HTML (which typically begins with <DOCTYPE html> or <html>) instead of JSON. Valid JSON cannot begin with a < character, so the JSON parser knows immediately the data isn’t valid JSON and produces one of the error messages mentioned above.

To fix this error you need to figure out why you’re getting HTML (or something else) instead of the JSON you expected. To do this you need to log the data you’re trying to parse to the console.

If you’re using fetch()

Use this approach if your code looks something like this:

fetch('https://example.com/some/path/to/json')
.then(function (response) {
    return response.json();
})
.then(function (data) {
    // Do something with data
});

In this case the error is thrown when response.json() tries to run and fails to parse the data from the server as JSON. You can add a function to handle the error and display the raw text of the response body from the server and log it to the console (see notes about commented lines below):

var responseClone; // 1
fetch('https://example.com/some/path/to/json')
.then(function (response) {
    responseClone = response.clone(); // 2
    return response.json();
})
.then(function (data) {
    // Do something with data
}, function (rejectionReason) { // 3
    console.log('Error parsing JSON from response:', rejectionReason, responseClone); // 4
    responseClone.text() // 5
    .then(function (bodyText) {
        console.log('Received the following instead of valid JSON:', bodyText); // 6
    });
});

Here’s an explanation of each line with a numbered comment:

  1. responseClone variable is required to hold a clone of the response object because the body of a response can only be read once. When response.json() is called the body of the original response is read, which means it cannot be read again when handling the JSON parse error. Cloning the response to responseClone provides two copies of the response body to work with; one in the original response to use with response.json() and another to use with responseClone.text() if response.json() fails.

  2. This line populates the responseClone variable with a clone of the response received from the server.

  3. A second function argument is passed to the then() function that follows the response.json() call. This second function will be called if the promise from response.json() is rejected (i.e. a JSON error is encountered).

  4. This line logs the rejectionReason from the rejected response.json() promise and the responseClone so it can be examined if needed (the HTTP status code is often useful for debugging, for example).

  5. Instead of trying to parse the response body from the server as JSON it is processed as raw text.

  6. The body text is logged to the console for examination.

If you’re using JSON.parse()

Use this method if the code that’s throwing the error looks like this:

JSON.parse(data);

In this case you can log the data to the console if an error is encountered to see what it contains:

try {
    JSON.parse(data);
}
catch (error) {
    console.log('Error parsing JSON:', error, data);
}

What do I do next?

Once you can see the data that’s causing the JSON parse error it will hopefully provide a clue as to why you’re not getting the valid JSON you expect. Some of the most common issues that lead to this error are:

  • If you see HTML indicating a 404 Not Found error instead of the JSON you expect check the URL you’re passing to fetch() and make sure its correct.

  • If you see HTML indicating a server error (such as a 500 error code) examine your server’s error logs to determine why your server is encountering an error instead of providing the JSON you expect.

  • If you see nothing or an unusual jumble of characters check your variable assignments and character encodings.

May 23, 2022

Umar Hansa

On this page

  • Anticipate potential network errors
    • Examples of user errors
    • Examples of environmental changes
    • Examples of errors with the video-sharing website
  • Handle errors with the Fetch API
    • When the Fetch API throws errors
    • When the network status code represents an error
    • When there is an error parsing the network response
    • When the network request must be canceled before it completes
  • Conclusion

This article demonstrates some error handling approaches when working with the Fetch API. The Fetch API lets you make a request to a remote network resource. When you make a remote network call, your web page becomes subject to a variety of potential network errors.

The following sections describe potential errors and describe how to write code that provides a sensible level of functionality that is resilient to errors and unexpected network conditions. Resilient code keeps your users happy and maintains a standard level of service for your website.

Anticipate potential network errors #

This section describes a scenario in which the user creates a new video named "My Travels.mp4" and then attempts to upload the video to a video-sharing website.

When working with Fetch, it’s easy to consider the happy path where the user successfully uploads the video. However, there are other paths that are not as smooth, but for which web developers must plan. Such (unhappy) paths can happen due to user error, through unexpected environmental conditions, or because of a bug on the video-sharing website.

Examples of user errors #

  • The user uploads an image file (such as JPEG) instead of a video file.
  • The user begins uploading the wrong video file. Then, part way through the upload, the user specifies the correct video file for upload.
  • The user accidentally clicks «Cancel upload» while the video is uploading.

Examples of environmental changes #

  • The internet connection goes offline while the video is uploading.
  • The browser restarts while the video is uploading.
  • The servers for the video-sharing website restart while the video is uploading.

Examples of errors with the video-sharing website #

  • The video-sharing website cannot handle a filename with a space. Instead of "My Travels.mp4", it expects a name such as "My_Travels.mp4" or "MyTravels.mp4".
  • The video-sharing website cannot upload a video that exceeds the maximum acceptable file size.
  • The video-sharing website does not support the video codec in the uploaded video.

These examples can and do happen in the real world. You may have encountered such examples in the past! Let’s pick one example from each of the previous categories, and discuss the following points:

  • What is the default behavior if the video-sharing service cannot handle the given example?
  • What does the user expect to happen in the example?
  • How can we improve the process?
Action The user begins uploading the wrong video file. Then, part way through the upload, the user specifies the correct video file for upload.
What happens by default The original file continues to upload in the background while the new file uploads at the same time.
What the user expects The user expects the original upload to stop so that no extra internet bandwidth is wasted.
What can be improved JavaScript cancels the Fetch request for the original file before the new file begins to upload.
Action The user loses their internet connection part way through uploading the video.
What happens by default The upload progress bar appears to be stuck on 50%. Eventually, the Fetch API experiences a timeout and the uploaded data is discarded. When internet connectivity returns, the user has to reupload their file.
What the user expects The user expects to be notified when their file cannot be uploaded, and they expect their upload to automatically resume at 50% when they are back online.
What can be improved The upload page informs the user of internet connectivity issues, and reassures the user that the upload will resume when internet connectivity has resumed.
Action The video-sharing website cannot handle a filename with a space. Instead of «My Travels.mp4», it expects names such as «My_Travels.mp4» or «MyTravels.mp4».
What happens by default The user must wait for the upload to completely finish. Once the file is uploaded, and the progress bar reads «100%», the progress bar displays the message: «Please try again.»
What the user expects The user expects to be told of filename limitations before upload begins, or at least within the first second of uploading.
What can be improved Ideally, the video-sharing service supports filenames with spaces. Alternative options are to notify the user of filename limitations before uploading begins. Or, the video-sharing service should reject the upload with a detailed error message.

Handle errors with the Fetch API #

Note that the following code examples use top-level await (browser support) because this feature can simplify your code.

When the Fetch API throws errors #

This example uses a try/catch block statement to catch any errors thrown within the try block. For example, if the Fetch API cannot fetch the specified resource, then an error is thrown. Within a catch block like this, take care to provide a meaningful user experience. If a spinner, a common user interface that represents some sort of progress, is shown to the user, then you could take the following actions within a catch block:

  1. Remove the spinner from the page.
  2. Provide helpful messaging that explains what went wrong, and what options the user can take.
  3. Based on the available options, present a «Try again» button to the user.
  4. Behind the scenes, send the details of the error to your error-tracking service, or to the back-end. This action logs the error so it can be diagnosed at a later stage.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}

At a later stage, while you diagnose the error that you logged, you can write a test case to catch such an error before your users are aware something is wrong. Depending on the error, the test could be a unit, integration, or acceptance test.

When the network status code represents an error #

This code example makes a request to an HTTP testing service that always responds with the HTTP status code 429 Too Many Requests. Interestingly, the response does not reach the catch block. A 404 status, amongst certain other status codes, does return a network error but instead resolves normally.

To check that the HTTP status code was successful, you can use any of the following options:

  • Use the Response.ok property to determine whether the status code was in the range from 200 to 299.
  • Use the Response.status property to determine whether the response was successful.
  • Use any other metadata, such as Response.headers, to assess whether the response was successful.
let response;

try {
response = await fetch('https://httpbin.org/status/429');
} catch (error) {
console.log('There was an error', error);
}

// Uses the 'optional chaining' operator
if (response?.ok) {
console.log('Use the response here!');
} else {
console.log(`HTTP Response Code: ${response?.status}`)
}

The best practice is to work with people in your organization and team to understand potential HTTP response status codes. Backend developers, developer operations, and service engineers can sometimes provide unique insight into possible edge cases that you might not anticipate.

When there is an error parsing the network response #

This code example demonstrates another type of error that can arise with parsing a response body. The Response interface offers convenient methods to parse different types of data, such as text or JSON. In the following code, a network request is made to an HTTP testing service that returns an HTML string as the response body. However, an attempt is made to parse the response body as JSON, throwing an error.

let json;

try {
const response = await fetch('https://httpbin.org/html');
json = await response.json();
} catch (error) {
if (error instanceof SyntaxError) {
// Unexpected token < in JSON
console.log('There was a SyntaxError', error);
} else {
console.log('There was an error', error);
}
}

if (json) {
console.log('Use the JSON here!', json);
}

You must prepare your code to take in a variety of response formats, and verify that an unexpected response doesn’t break the web page for the user.

Consider the following scenario: You have a remote resource that returns a valid JSON response, and it is parsed successfully with the Response.json() method. It may happen that the service goes down. Once down, a 500 Internal Server Error is returned. If appropriate error-handling techniques are not used during the parsing of JSON, this could break the page for the user because an unhandled error is thrown.

When the network request must be canceled before it completes #

This code example uses an AbortController to cancel an in-flight request. An in-flight request is a network request that has started but has not completed.

The scenarios where you may need to cancel an in-flight request can vary, but it ultimately depends on your use case and environment. The following code demonstrates how to pass an AbortSignal to the Fetch API. The AbortSignal is attached to an AbortController, and the AbortController includes an abort() method, which signifies to the browser that the network request should be canceled.

const controller = new AbortController();
const signal = controller.signal;

// Cancel the fetch request in 500ms
setTimeout(() => controller.abort(), 500);

try {
const url = 'https://httpbin.org/delay/1';
const response = await fetch(url, { signal });
console.log(response);
} catch (error) {
// DOMException: The user aborted a request.
console.log('Error: ', error)
}

Conclusion #

One important aspect of handling errors is to define the various parts that can go wrong. For each scenario, make sure you have an appropriate fallback in place for the user. With regards to a fetch request, ask yourself questions such as:

  • What happens if the target server goes down?
  • What happens if Fetch receives an unexpected response?
  • What happens if the user’s internet connection fails?

Depending on the complexity of your web page, you can also sketch out a flowchart which describes the functionality and user interface for different scenarios.

Return to all articles

Понравилась статья? Поделить с друзьями:
  • Error parsing pcc subspaces from pcct astra linux
  • Error parsing manifest entries in
  • Error parsing layout and style files
  • Error parsing json response null перевод
  • Error parsing jndi name