Solve the extremely difficult problem of catching exceptions but being unable to read exception information in the node project

This project integrates the interface code of the third-party NeteaseCloudMusicApi project. I did not use its interface directly because I needed to run another npm run to open a port, which was very troublesome.

So I made up my mind to use the code splitting method to integrate part of the API interface code of this API project into my own project. Of course, the premise is that you must be able to understand its code before you can split it, otherwise you will have no way to start.

Finally, I got it all done. The process was very complicated, so I split its API code into my own project.

But there is a problem. Sometimes a 404 error will be reported when requesting songs.

But this 404 error report is obviously incorrect, because I have already buried it in the code:

The above proves: This interface request has actually matched the route, so it should never be a 404 error!

Then I checked the code and found that the error handling code of this third-party API actually wrote 404!

This is wrong. It should definitely be at least 500, but this is not enough. You must at least know what the error is.

Therefore, write the value of its msg as the captured err

I thought I would be able to see the specific exception information after processing this way, but the actual return result is still an empty object:

The problem becomes tricky. The exception is obviously caught, but why can’t it be printed out?

It seems that we must first look at the original information of this err? So at the beginning of the catch code block, console.log this err:

Then this exception message is printed:

The error is reported as follows :

get Err==> TypeError: Cannot read property ‘sort’ of undefined
at Object.module.exports [as module] (D:\VueCode\VueProject\myqqmusic\src\registerRouter\\
etEaseApi\modules\song_url.js:33:10)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async D:\VueCode\VueProject\myqqmusic\src\registerRouter\\
etEaseApi\routes.js:69:40

But why can’t I get the value when I assign err to msg? Then I looked at the data structure of this error during breakpoint debugging:

Then I analyzed it based on GPT. It stands to reason that the specific information of the exception should be obtained through err.message and err.stack:

Then I did see the specific information of the exception, and this time no null value {} was reported:

Okay, to summarize: the Error object in Javascript must obtain specific information through the message or stack attribute,

That is, in the form of err.message or err.stack, the Error object cannot be assigned directly to a variable! ! ! Otherwise, the value obtained by the variable is an empty object!

But this kind of error message is too ugly. You should follow the error reporting guidelines to find the place where the exception is triggered:

get Err==> TypeError: Cannot read property ‘sort’ of undefined
at Object.module.exports [as module] (D:\VueCode\VueProject\myqqmusic\src\registerRouter\\
etEaseApi\modules\song_url.js:33:10)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async D:\VueCode\VueProject\myqqmusic\src\registerRouter\\
etEaseApi\routes.js:69:40

According to the error message above, find line 33 of song_url.js:

This place says that result does not have a sort attribute, then the result itself is most likely undefined!

So it is very necessary to see what its parent res is.

Then through breakpoint debugging, you can see that there is no data attribute under res, so the result must be undefined.

No wonder result.sort triggers the Cannot read property ‘sort’ of undefined exception.

And here you can see the real reason for the exception:

// This exception information is placed in res.body

{
code: -460,
message: “The network is too congested, please try again later!”,
}

Therefore, before obtaining the result through res.body.data, you must first determine whether res.body has the data attribute.

In other words, judge whether the return status of res is normal, because it is a bit too one-sided to judge whether the return status is normal based only on whether res.body has a data attribute

Then I found an example of a successful request:

You can see that when the request is successful: not only does res.body have a data attribute, but res.body.code is also equal to 200,

So the following code should be added: actively throw an exception when the res request fails, and use res.body as the exception information:

if (res.body.code != 200 ) {

throw new Error(res.body) // Because the details of the exception are stored in res.body

}

But in the external exception interception mentioned earlier (catch err code block), the result is: msg failed to correctly deconstruct the exception information, and what is displayed is: [object Object]

Regarding this issue, I have searched for a long time and searched a lot of information. I have tried many times but have not been able to solve the problem.

It can be said: This is the most difficult part of this troubleshooting

Then, I tried to chat from chatgpt, hoping to find the answer.

At first, I tried several times according to the method it gave, but it still didn’t work.

Finally, I asked a key God question:

You don’t understand what I mean. For example, the original exception message is res.body=”{“code”:-460,”message”:”The network is too congested, please try again later! “}” , then I threw new Error(JSON.stringify(res.body)) and threw this exception. I asked catch how to get the exception information in json format.

Then chatgpt finally gave the correct answer:

I understand your problem. If your exception message is a JSON string, you can parse it using JSON.parse in a catch block to get the raw JSON object. Here is an example:

try {
  const res = { body: '{"code":-460,"message":"The network is too congested, please try again later!"}' };
  throw new Error(JSON.stringify(res.body));
} catch (error) {
  try {
    // Attempt to parse the exception message into JSON
    const errorData = JSON.parse(error.message);
    console.log("Error code:", errorData.code);
    console.log("Error message:", errorData.message);
  } catch (parseError) {
    // Handle cases where parsing JSON fails
    console.error("Error parsing JSON:", parseError);
  }
}

In this example, we first throw an exception and the exception message is a JSON string. Then in the catch block, we try to use JSON.parse to parse the exception message into a JSON object and access the properties within it. If parsing fails, we catch the parsing error and handle it.

In this way you can get the original JSON object information. But be careful when handling JSON parsing failures, as the exception message may not always be a valid JSON string.

There are two key points here:

1. When customizing exception information: The new Error constructor usually receives a string as the parameter of the error message, instead of an object.

If the received parameter is an object then must be converted into a json string through the JSON.stringify() method

2. When it is predicted that the captured error is a json string, then the JSON.parse() method must be used to convert the error.message into an object object, otherwise the printed message will be [object Object]

Therefore, the code needs to be modified like this:

Part of the exception that is actively thrown:

if (res.body.code != 200 ) {

// Note that the parameter of new Error here cannot be an object, but must be a string! ! !

//So res.body must be converted into a string through JSON.stringify

throw new Error(JSON.stringify(res.body))

}

Exception catching place:

catch (err) {

// Because err.message is a JSON string, it must be converted into an object through JSON.parse.

// Otherwise msg: errData will become: Error: [object Object] when assigned

// In this way, msg cannot get the value and becomes a null value.

const errData = JSON.parse(err.message) //Key point: Must use JSON.parse method

console.log(“Error message:”, errData.message);

console.log(“get Err==>”, err)

console.log(‘[ERR]’, decode(req.originalUrl), {

status: err.status,

body: err.body,

})

if (!err.body) {

res.status(500).send({

code: 500,

data: null,

msg: errData,

})

return

}

Problem solved: The foreground msg information is finally displayed normally, no longer [object Object]

Summary:

1. The Error object in Javascript must obtain its specific information through the message or stack attribute,

That is, in the form of err.message or err.stack.

You cannot assign the entire Error object directly to a variable! ! ! Otherwise, the value obtained by the variable is an empty object!

2. When customizing exception information: The new Error constructor usually receives a string as the parameter of the error message, instead of an object.

If the received parameter is an object, then the object must be converted into a json string through the JSON.stringify() method

// The part that actively throws exceptions

// If the received parameter is an object, then the object must be converted into a json string through the JSON.stringify() method

new Error(JSON.stringify(err_obj))

3. When it is predicted that the captured error is a json string, then the JSON.parse() method must be used to convert the error.message into an object object, otherwise the printed message will be [object Object]

// The part that catches the exception

catch(err) {

// When it is known that err is a json string, you must use the JSON.parse() method to convert error.message into an object object, otherwise what is printed will be [object Object]< /strong>

errData = JSON.parse(err.message) // Using the JSON.parse method is key!

}

syntaxbug.com © 2021 All Rights Reserved.