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

process: Add code to warnings, assign codes to deprecations #10116

Closed
wants to merge 3 commits into from

Conversation

@jasnell
Copy link
Member

jasnell commented Dec 4, 2016

Checklist
  • make -j8 test (UNIX), or vcbuild test nosign (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

process, lib

Description of change

As discussed at the Node.js Interactive Collaboration Summit in Austin last week, this PR adds a few new capabilities that should make it easier to make dealing with runtime deprecation warnings in Node.js easier.

  1. A static identifier code can be assigned to all process warnings. These are specified as either a new optional argument to process.emitWarning() or as a code property on an Error object passed into process.emitWarning(). Within the process.on('warning') event handler, these can be accessed via the code property on the warning object.

  2. A new --redirect-warnings=file command line argument and matching NODE_REDIRECT_WARNINGS=file environment variable is added to allow process warning output to be printed to the given file as opposed to dumping to stderr. This will allow, for instance, npm and other applications spawning node process instances to capture warning output with less noise to the console.

  3. Every runtime and documentation-only deprecation in Node.js is assigned a static identifier code.

  4. A new deprecations.md file is added to the API documentation that lists each of the runtime and documentation-only deprecation codes assigned. For future work (perhaps a good first contribution for new Node.js contributors), it would be helpful to expand the details in deprecations.md to include links to the relevant sections in other parts of the API documentation as well as expanded descriptions of why the APIs are deprecated and what the alternatives are. /cc @nodejs/documentation

Note: This PR is currently semver-major because it adds improved type checking to the input on process.emitWarning() to ensure that both the warning name and the identifier code are strings.
If this PR is backported to older Node.js release streams, the backport can be landed as a semver-minor if and only if the additional type checking on the name argument is removed.

/cc @ashleygwilliams

@jasnell
Copy link
Member Author

jasnell commented Dec 4, 2016

doc/api/cli.md Outdated
-->

Write process warnings to the given file instead of printing to stderr but
only if the file does not already exist.

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

Why “only if the file does not already exist”? I’m not sure I’d expect that, and it sounds a bit like that might interfere with programmatic use of the API.

Is this about multiple node processes sharing the same env var?

This comment has been minimized.

@jasnell

jasnell Dec 4, 2016 Author Member

I'm not entirely sure about the only if the file does not already exist part either. For now I have it this way just to ensure that something important isn't accidentally overwritten.

This comment has been minimized.

@Fishrock123

Fishrock123 Dec 4, 2016 Member

Maybe we should just append?

This comment has been minimized.

@jasnell

jasnell Dec 4, 2016 Author Member

Just appending works also. Doing so is pretty safe when dealing with multiple node processes since the warning output includes the pid

doc/api/deprecations.md Outdated
`OutgoingMessage.prototype.flushHeaders()` instead.

<a id="DEP00002"></a>
### DEP00002: require('_linklist')

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

This should probably be \_linklist (including the \)

doc/api/process.md Outdated
<!-- YAML
added: v6.0.0
-->

* `warning` {String | Error} The warning to emit.
* `name` {String} When `warning` is a String, `name` is the name to use
for the warning. Default: `Warning`.
* `code` {String} A unique identifier for the warning.

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

I’m not sure the semantic difference between name and code is obvious here?

This comment has been minimized.

@Fishrock123

Fishrock123 Dec 4, 2016 Member

Name may be better as "type"?

This comment has been minimized.

@jasnell

jasnell Dec 4, 2016 Author Member

type is a good option

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

Name may be better as "type"?

Remember that .name is inherited from the Error classes – I don’t think we can change that.

I’m also not worried that much about the naming, a bit of clarification might be all that’s needed

This comment has been minimized.

@jasnell

jasnell Dec 4, 2016 Author Member

The argument can be called type with name still used on the error object. I'm not overly concerned about the difference there.

lib/buffer.js Outdated
* The Buffer() construtor is deprecated in documentation and should not be
* used moving forward. Rather, developers should use one of the three new
* factory APIs: Buffer.from(), Buffer.allocUnsafe() or Buffer.alloc() based on
* their specific needs. There is no hard deprecation because of the extent to

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

nit: Runtime deprecation? ;)

lib/buffer.js Outdated
* used moving forward. Rather, developers should use one of the three new
* factory APIs: Buffer.from(), Buffer.allocUnsafe() or Buffer.alloc() based on
* their specific needs. There is no hard deprecation because of the extent to
* which the Buffer constructor is used in the ecosystem currently -- a hard

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

(ditto)

lib/internal/process/warning.js Outdated
const prefix = `(${process.release.name}:${process.pid}) `;

exports.setup = setupProcessWarnings;

var fd;
function acquireFd() {
if (!fd) {

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

Nit: fd === undefined

lib/internal/process/warning.js Outdated
}
if (code && typeof code !== 'string')
throw new TypeError('`code` must be a String');
if (name && typeof name !== 'string')

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

nit: name !== undefined and code !== undefined

lib/internal/util.js Outdated
@@ -51,11 +51,18 @@ exports._deprecate = function(fn, msg) {
return fn;
}

if (code && typeof code !== 'string')

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

(ditto)

src/node_config.cc Outdated
@@ -44,6 +45,16 @@ void InitConfig(Local<Object> target,

if (config_preserve_symlinks)
READONLY_BOOLEAN_PROPERTY("preserveSymlinks");

if (config_warning_file != NULL) {

This comment has been minimized.

@addaleax

addaleax Dec 4, 2016 Member

nit: nullptr

@jasnell jasnell force-pushed the jasnell:warning-additions branch 2 times, most recently Dec 4, 2016
@jasnell
Copy link
Member Author

jasnell commented Dec 4, 2016

@addaleax @Fishrock123 ... updated to address the nits. Updated the --redirect-warnings to append and renamed the emitWarning() name argument to type

@@ -706,14 +706,15 @@ console.log(process.env.test);
// => 1
```

## process.emitWarning(warning[, name][, ctor])
## process.emitWarning(warning[, type[, code]][, ctor])

This comment has been minimized.

@silverwind

silverwind Dec 5, 2016 Contributor

I think a options object {type, code, ctor} is in order here.

This comment has been minimized.

@sam-github

sam-github Jan 10, 2017 Contributor

I think this is basically just intended for internal use, so doesn't need a nice API, and changing the call signature would cause a fair amount of internal churn.

Honestly, I don't think it should be an API at all, maybe we can deprecate it? Seriously, why do we want to expose this to users of node? We expect them to be using it to emit their own warnings?

This comment has been minimized.

@addaleax

addaleax Jan 10, 2017 Member

Honestly, I don't think it should be an API at all, maybe we can deprecate it? Seriously, why do we want to expose this to users of node? We expect them to be using it to emit their own warnings?

Fwiw it was deliberately added as an outward-facing API in c6656db (released in v6.0.0) with that intention, yes. I don’t mind it being there.

This comment has been minimized.

@jasnell

jasnell Jan 10, 2017 Author Member

It was exposed this way because we had users asking to be able to use it also. I'm definitely -1 on deprecating it as I have found it to be quite useful

This comment has been minimized.

@sam-github

sam-github Jan 10, 2017 Contributor

OK, then I agree with @silverwind, its become an ugly API, with three strings in a row, 2 of which are optional, and remembering the arg order isn't reasonably possible. @addaleax the problem with APIs is they rot with time, becoming harder and harder to use and support, like this one is now, which is why I am generally in favour of not adding unnecessary APIs, even if when they are useful. I guess given the alternative of adding a second options-based call pattern, and supporting the old 3 argument call for backwards compatibility, and documenting both of them, or just adding another optional string arg, better to do the latter. If we ever add a 4th string, though, it will no longer be reasonable.

This comment has been minimized.

@silverwind

silverwind Jan 11, 2017 Contributor

@sam-github My thoughts exactly. Supporting two call signatures is easy and enables easier future additons.

This comment has been minimized.

@jasnell

jasnell Jan 11, 2017 Author Member

The API already supports two call signatures. The first argument can be passed in as a pre-constructed Error object with all of the relevant properties set:

const warning = new Error('This is a warning');
warning.name = 'CustomWarning';
warning.code = 'ABC123';
process.emitWarning(warning);

is equivalent to:

process.emitWarning('This is a warning', 'CustomWarning', 'ABC123');

Having an options object when we can already pass in an Error object would be rather pointless, IMO

This comment has been minimized.

@sam-github

sam-github Jan 11, 2017 Contributor

That Error behaviour isn't well documented. I read carefully, and I see now that its implied by by the "If warning is passed as an Error object, it will be passed through .... unmodified" sentence.

I think the docs could be clearer, but that's an aside from this PR.

This comment has been minimized.

@jasnell

jasnell Jan 11, 2017 Author Member

It's not just implied, it's explicitly stated in the arguments list that warning can be a string or an Error, and an example of passing an Error is shown immediately following the If warning is passed as an Error object... sentence. Immediately following the example is a clear statement that a TypeError will be thrown is warning is anything other than a string or Error object. The docs seem pretty explicit about it.

@jasnell
Copy link
Member Author

jasnell commented Dec 5, 2016

doc/api/deprecations.md Outdated

Type: Documentation-only

The `Buffer()` and `new Buffer()` constructors are considered to be deprecated

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

Buffer() is not considered as a constructor

doc/api/deprecations.md Outdated
As an alternative, use of the following methods of constructing `Buffer` objects
is strongly recommended:

* `Buffer.alloc(size[, fill[, encoding]])` - Create a `Buffer` with

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

Providing links to these methods will be helpful.

doc/api/deprecations.md Outdated

Type: Runtime

The `crypto.Credentials` class is deprecated. Please Uuse `tls.SecureContext`

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

use

doc/api/deprecations.md Outdated
Type: Runtime

The `constants` module has been deprecated. When requiring access to constants
relevant to specific Node.js built in modules, developers should instead refer

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

built-in

doc/api/deprecations.md Outdated

Type: Runtime

The `fs.read()` legacy String interface is deprecated. Use the Buffer API as

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

We explicitly ask the readers to refer documentation, it would be better if we had the link here.

doc/api/deprecations.md Outdated

Type: Documentation-only

The `require.extensions` API has been deprecated.

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

property or API

lib/constants.js Outdated
@@ -1,8 +1,9 @@
'use strict';

// This module is soft-deprecated. Users should be directed towards using
// This module is deprecate in docs. Users should be directed towards using

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

doc-deprecated?

if (warning.code) {
output(`${prefix}[${warning.code}] ${toString.apply(warning)}`);
} else {
output(`${prefix}${toString.apply(warning)}`);

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

Should there be a space after ${prefix}?

This comment has been minimized.

@jasnell

jasnell Dec 5, 2016 Author Member

No, the ${prefix} includes a space already

src/node_config.cc Outdated
if (config_warning_file != nullptr) {
target->DefineOwnProperty(env->context(),
OneByteString(env->isolate(), "warningFile"),
String::NewFromUtf8(env->isolate(),

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

Can we split them into multiple variables?

test/parallel/test-process-redirect-warnings-env.js Outdated
fork(warnmod, {env: {NODE_REDIRECT_WARNINGS: warnpath}})
.on('exit', common.mustCall(() => {
fs.stat(warnpath, common.mustCall((err, stat) => {
assert(!err);

This comment has been minimized.

@thefourtheye

thefourtheye Dec 5, 2016 Contributor

assert.ifError

@silverwind
Copy link
Contributor

silverwind commented Dec 5, 2016

Switching to an options object would just add confusion, I think.

It's more of a general adivce to design APIs in a extendable way. I think that once a function takes 3 or more arguments, it gets to a point where the user has to lookup the arguments on less-frequently used functions, which could've been avoided if it would be designed with a options object from the start.

@Fishrock123
Copy link
Member

Fishrock123 commented Dec 5, 2016

What do we do about things we have to un-deprecate? Just remove them from the doc? Or mark them as no longer deprecated?

@jasnell
Copy link
Member Author

jasnell commented Dec 5, 2016

@jasnell jasnell force-pushed the jasnell:warning-additions branch 2 times, most recently Dec 5, 2016
@jasnell
Copy link
Member Author

jasnell commented Dec 5, 2016

@silverwind ... I don't disagree, but as I said, this API already provides the option of passing in an Error object as the first argument. Given that, I don't see significant value in providing an options object

@jasnell
Copy link
Member Author

jasnell commented Dec 5, 2016

@thefourtheye ... updated to address your feedback. I squashed and force pushed to keep things organized.

@jasnell jasnell force-pushed the jasnell:warning-additions branch 2 times, most recently Dec 5, 2016
@jasnell
Copy link
Member Author

jasnell commented Dec 5, 2016

@jasnell jasnell force-pushed the jasnell:warning-additions branch Dec 5, 2016
@jasnell
Copy link
Member Author

jasnell commented Dec 6, 2016

@nodejs/ctc ... thoughts on this?

@trevnorris
Copy link
Contributor

trevnorris commented Dec 9, 2016

@jasnell there a way to automatically track the next deprecation code? feel it could be error prone or frustrating to grep all the current ones to find the next.

@jasnell
Copy link
Member Author

jasnell commented Dec 9, 2016

@trevnorris
Copy link
Contributor

trevnorris commented Dec 9, 2016

@jasnell ah. missed deprecations.md b/c github refrained from loading it. okay, seems reasonable enough.

@jasnell jasnell requested review from mscdex and ofrobots Dec 11, 2016
@sam-github
Copy link
Contributor

sam-github commented Jul 21, 2017

I backported 03e89b3 to 6.x, the other commits look semver-major to me, as they add deprecation code and change the output format. Do I misunderstand?

sam-github added a commit to sam-github/node that referenced this pull request Jul 24, 2017
The --redirect-warnings command line argument allows process warnings
to be written to a specified file rather than printed to stderr.

Also adds an equivalent NODE_REDIRECT_WARNINGS environment variable.

If the specified file cannot be opened or written to for any reason,
the argument is ignored and the warning is printed to stderr.

If the file already exists, it will be appended to.

PR-URL: nodejs#10116
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Michal Zasso <targos@protonmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
sam-github added a commit that referenced this pull request Jul 24, 2017
The --redirect-warnings command line argument allows process warnings
to be written to a specified file rather than printed to stderr.

Also adds an equivalent NODE_REDIRECT_WARNINGS environment variable.

If the specified file cannot be opened or written to for any reason,
the argument is ignored and the warning is printed to stderr.

If the file already exists, it will be appended to.

Backport-PR-URL: #14418
PR-URL: #10116
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Michal Zasso <targos@protonmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Jeyanthinath added a commit to Jeyanthinath/node that referenced this pull request Jul 26, 2017
The --redirect-warnings command line argument allows process warnings
to be written to a specified file rather than printed to stderr.

Also adds an equivalent NODE_REDIRECT_WARNINGS environment variable.

If the specified file cannot be opened or written to for any reason,
the argument is ignored and the warning is printed to stderr.

If the file already exists, it will be appended to.

Backport-PR-URL: nodejs#14418
PR-URL: nodejs#10116
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Michal Zasso <targos@protonmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
@refack refack moved this from In Progress to Done in Error Codes Aug 30, 2017
sam-github added a commit to sam-github/node that referenced this pull request Oct 10, 2017
The --redirect-warnings command line argument allows process warnings
to be written to a specified file rather than printed to stderr.

Also adds an equivalent NODE_REDIRECT_WARNINGS environment variable.

If the specified file cannot be opened or written to for any reason,
the argument is ignored and the warning is printed to stderr.

If the file already exists, it will be appended to.

PR-URL: nodejs#10116
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Michal Zasso <targos@protonmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
MylesBorins added a commit that referenced this pull request Oct 16, 2017
The --redirect-warnings command line argument allows process warnings
to be written to a specified file rather than printed to stderr.

Also adds an equivalent NODE_REDIRECT_WARNINGS environment variable.

If the specified file cannot be opened or written to for any reason,
the argument is ignored and the warning is printed to stderr.

If the file already exists, it will be appended to.

Backport-PR-URL: #12677
PR-URL: #10116
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Michal Zasso <targos@protonmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Oct 17, 2017
MylesBorins added a commit that referenced this pull request Oct 25, 2017
The --redirect-warnings command line argument allows process warnings
to be written to a specified file rather than printed to stderr.

Also adds an equivalent NODE_REDIRECT_WARNINGS environment variable.

If the specified file cannot be opened or written to for any reason,
the argument is ignored and the warning is printed to stderr.

If the file already exists, it will be appended to.

Backport-PR-URL: #12677
PR-URL: #10116
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Michal Zasso <targos@protonmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Nov 3, 2017
MylesBorins added a commit that referenced this pull request Nov 6, 2017
Notable Changes:

* assert:
  - assert.fail() can now take one or two arguments (Rich Trott)
    #12293
* crypto:
  - add sign/verify support for RSASSA-PSS (Tobias Nießen)
    #11705
* deps:
  - upgrade openssl sources to 1.0.2m (Shigeki Ohtsu)
    #16691
  - upgrade libuv to 1.15.0 (cjihrig)
    #15745
  - upgrade libuv to 1.14.1 (cjihrig)
    #14866
  - upgrade libuv to 1.13.1 (cjihrig)
    #14117
  - upgrade libuv to 1.12.0 (cjihrig)
    #13306
* fs:
  - Add support for fs.write/fs.writeSync(fd, buffer, cb) and
    fs.write/fs.writeSync(fd, buffer, offset, cb) as documented
    (Andreas Lind) #7856
* inspector:
  - enable --inspect-brk (Refael Ackermann)
    #12615
* process:
  - add --redirect-warnings command line argument (James M Snell)
    #10116
* src:
  - allow CLI args in env with NODE_OPTIONS (Sam Roberts)
    #12028)
  - --abort-on-uncaught-exception in NODE_OPTIONS (Sam Roberts)
    #13932
  - allow --tls-cipher-list in NODE_OPTIONS (Sam Roberts)
    #13172
  - use SafeGetenv() for NODE_REDIRECT_WARNINGS (Sam Roberts)
    #12677
* test:
  - remove common.fail() (Rich Trott)
    #12293

PR-URL: #16263
MylesBorins added a commit that referenced this pull request Nov 7, 2017
Notable Changes:

* assert:
  - assert.fail() can now take one or two arguments (Rich Trott)
    #12293
* crypto:
  - add sign/verify support for RSASSA-PSS (Tobias Nießen)
    #11705
* deps:
  - upgrade openssl sources to 1.0.2m (Shigeki Ohtsu)
    #16691
  - upgrade libuv to 1.15.0 (cjihrig)
    #15745
  - upgrade libuv to 1.14.1 (cjihrig)
    #14866
  - upgrade libuv to 1.13.1 (cjihrig)
    #14117
  - upgrade libuv to 1.12.0 (cjihrig)
    #13306
* fs:
  - Add support for fs.write/fs.writeSync(fd, buffer, cb) and
    fs.write/fs.writeSync(fd, buffer, offset, cb) as documented
    (Andreas Lind) #7856
* inspector:
  - enable --inspect-brk (Refael Ackermann)
    #12615
* process:
  - add --redirect-warnings command line argument (James M Snell)
    #10116
* src:
  - allow CLI args in env with NODE_OPTIONS (Sam Roberts)
    #12028)
  - --abort-on-uncaught-exception in NODE_OPTIONS (Sam Roberts)
    #13932
  - allow --tls-cipher-list in NODE_OPTIONS (Sam Roberts)
    #13172
  - use SafeGetenv() for NODE_REDIRECT_WARNINGS (Sam Roberts)
    #12677
* test:
  - remove common.fail() (Rich Trott)
    #12293

PR-URL: #16263
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.