Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for error handling #259

Closed
wants to merge 7 commits into from
Closed

Documentation for error handling #259

wants to merge 7 commits into from

Conversation

NickNaso
Copy link
Member

@NickNaso NickNaso commented May 3, 2018

First step on writing documentation for error handling.

doc/error.md Outdated

If C++ exceptions are enabled (for more info see: [Setup](setup.md) section),
then the **Error** class extends ```std::exception``` and enables integrated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For single line code I think you can just use a single backtick.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will provide to remove where necessary.

doc/error.md Outdated
### Constructor

Initializes a ```Error``` instance from an existing ```Error``` object.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been wresting with how to describe this, maybe "from an existing JavaScript Error object." The description as it stands sounds more like a copy constructor when it seems like this would be used more for JavaScript objects which have been acquired elsewhere.

doc/error.md Outdated
```

Throw the error as JavaScript exception.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I would move this above where the description normally goes and then update it to say "Throws"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

doc/error.md Outdated

Returns a pointer to a null-terminated string that is used to identify the
exception. This method can be used only if the eceptions mechanis is enabled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "exception mechanism"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this file is also missing

static NAPI_NO_RETURN void Fatal(const char* location, const char* message);

@@ -1,5 +1,138 @@
# Error handling

You are reading a draft of the next documentation and it's in continuos update so
if you don't find what you need please refer to:
[C++ wrapper classes for the ABI-stable C APIs for Node.js](https://nodejs.github.io/node-addon-api/)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is our feeling about this? I've seen some of the documentation updates leave it, but maybe it's the right time to start removing these designations.

/cc @mhdawson

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my thought, once we fill in the section lets remove the comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replied above at this point I'd say take it out.

The error handling represents one of the most important thing on implementing a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "Error handling represents one of the most important considerations when implementing a Node.js native add-on."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Node.js native add-on. When an error occurs in your C++ code you have to handle
and dispatch it correctly. **N-API** uses return values and JavaScript exceptions
for error handling. You can choice one method or other based on your preferences
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "You can choose return values or exception handling based on the mechanism that works best for your add-on."

The **Error** is a persistent reference (for more info see: [Object reference](object_reference.md)
section) to a JavaScript error object. Use of this class depends somewhat on
whether C++ exceptions are enabled at compile time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: avoid "somewhat", we want to be as descriptive as possible. If there are more nuances we should try to enumerate them.


- [Handling Errors With C++ Exceptions](#exceptions)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think this extra newline is necessary here


<a name="exceptions"></a>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra newline

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using markdownlint and it reports

[markdownlint] MD022/blanks-around-headers: Headers should be surrounded by blank lines

but if you want I can remove the extra space. Maybe in general we need to have a standard to follow.

The **Error** class is a representation of the JavaScript Error object that is thrown
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a guideline for these sorts of stylistic flairs? It seems like Error and Error are used in different scenarios throughout this file, what is the guideline we're following?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No at moment we haven't a stylistic standard to follow. My opinion is that we need one.

Following C++ statements will not be executed. The exception will bubble up as a
C++ exception of type **Error**, until it is either caught while still in C++, or
else automatically propataged as a JavaScript exception when returns to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "propagated"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "C++ statements following the throwing statement will not be executed. The exception throw is of type Error and can be handled in C++ as usual. If the exception is not handled in C++ it will automatically propagate to the JavaScript caller.


<a name="noexceptions"></a>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra newline

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe an example that shows rethrowing ?


If C++ exceptions are disabled (for more info see: [Setup](setup.md) section),
then the **Error** class does not extend ```std::exception```. This means that
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extra space after "Error"

If C++ exceptions are disabled (for more info see: [Setup](setup.md) section),
then the **Error** class does not extend ```std::exception```. This means that
any call to node-addon-api functions does not throw C++ exception.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "any calls to node-addon-api function do not throw C++ exceptions."

Copy link
Contributor

@kfarnung kfarnung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with some nits

doc/error.md Outdated

```cpp
TypeError(napi_env env, napi_value value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a typo, should be Error instead of TypeError.

doc/error.md Outdated

```cpp
TypeError(napi_env env, napi_value value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Believe this should Error not TypeError

- [Handling Errors Without C++ Exceptions](#noexceptions)

<a name="exceptions"></a>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? wondering why there is html here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to create an anchor with a friendly name that's not affected by changes to the name of the header. The same approach is used in the official CHANGELOG

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, just have not see it in other docs.

then the **Error** class extends ```std::exception``` and enables integrated
error-handling for C++ exceptions and JavaScript exceptions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If C++ exceptions are enabled then exceptions are converted and handled as C++ exceptions while in native code and as JavaScript exceptions in JavaScript code. What this means is that:

and then make the following bullet points:

If a JavaScript function called by C++ code via N-API throws a JavaScript
exception, then the N-API wrapper automatically converts and throws it as a C++
exception of type **Error**.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on return from the JavaScript code to the native method.

exception of type **Error**.

If a C++ exception of type **Error** escapes from a N-API C++ callback, then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On return from a native method, N-API will automatically convert a pending C++ exception to a JavaScript exception.

the N-API wrapper automatically converts and throws it as a JavaScript exception.

Therefore, catching a C++ exception of type **Error** prevents a JavaScript
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When C++ exceptions are enabled try/catch can be used to catch exceptions thrown from calls to JavaScript and then they can either be handled or rethrown before returning from a native method.

Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
if (result.IsEmpty()) return;
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to suggest that they should check using IsExceptionPending as that will work for methods that don't return a value as well.

Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
if (result.IsEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same goes here to check with IsExceptionPending

@mhdawson
Copy link
Member

mhdawson commented May 3, 2018

Overall looking good, just a few comments and suggestions.

@NickNaso
Copy link
Member Author

Completed fix proposed on first review

@NickNaso NickNaso removed the request for review from jschlight May 13, 2018 20:43
Copy link
Member

@mhdawson mhdawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mhdawson
Copy link
Member

@NickNaso I'm having trouble landing. Can you squash the commits and then I'll try again.

NickNaso added 2 commits June 6, 2018 01:03
First step of error documentation

Documentation for error handling

Complete fix proposed on first review
@NickNaso
Copy link
Member Author

NickNaso commented Jun 5, 2018

@mhdawson Could you try to land now?

@NickNaso
Copy link
Member Author

Hi @mhdawson I combined the work on this PR with #272. Please don't land this PR and if you want close it.

@mhdawson
Copy link
Member

Closing in favour of #272

@mhdawson mhdawson closed this Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants