Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions src/js/builtins/ConsoleObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,16 @@ export function createConsoleConstructor(console: typeof globalThis.console) {
if (inspectOptions !== undefined) {
validateObject(inspectOptions, "options.inspectOptions");

if (inspectOptions.colors !== undefined && options.colorMode !== undefined) {
throw $ERR_INCOMPATIBLE_OPTION_PAIR(
'Option "options.inspectOptions.color" cannot be used in combination with option "colorMode"',
);
// inspectOptions may be a Map keyed by stream, giving each stream its own
// options; a plain object applies to both.
const isPerStream = $isMap(inspectOptions);
for (const stream of [stdout, stderr]) {
const perStreamOptions = isPerStream ? inspectOptions.$get(stream) : inspectOptions;
if (perStreamOptions?.colors !== undefined && options.colorMode !== undefined) {
throw $ERR_INCOMPATIBLE_OPTION_PAIR(
'Option "options.inspectOptions.color" cannot be used in combination with option "colorMode"',
);
}
}
optionsMap.set(this, inspectOptions);
}
Expand Down Expand Up @@ -481,7 +487,8 @@ export function createConsoleConstructor(console: typeof globalThis.console) {
}
}

const options = optionsMap.get(this);
const inspectOptions = optionsMap.get(this);
const options = $isMap(inspectOptions) ? inspectOptions.$get(stream) : inspectOptions;
if (options) {
if (options.colors === undefined) {
options.colors = color;
Expand Down
5 changes: 4 additions & 1 deletion src/js/internal/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class ExceptionWithHostPort extends Error {
port?: number;
address: string;

constructor(err: number, syscall: string, address: string, port?: number) {
constructor(err: number, syscall: string, address: string, port?: number, additional?: string) {
// TODO(joyeecheung): We have to use the type-checked
// getSystemErrorName(err) to guard against invalid arguments from users.
// This can be replaced with [ code ] = errmap.get(err) when this method
Expand All @@ -70,6 +70,9 @@ class ExceptionWithHostPort extends Error {
} else if (address) {
details = ` ${address}`;
}
if (additional) {
details += ` - Local (${additional})`;
}

super(`${syscall} ${code}${details}`);

Expand Down
4 changes: 2 additions & 2 deletions src/js/node/net.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3135,7 +3135,7 @@ function afterConnect(status, handle, req, readable, writable) {
if (localAddress && (localPort = req.localPort)) {
details = localAddress + ":" + localPort;
}
const ex = new ExceptionWithHostPort(status, "connect", req.address, req.port);
const ex = new ExceptionWithHostPort(status, "connect", req.address, req.port, details);
if (details) {
ex.localAddress = req.localAddress;
ex.localPort = req.localPort;
Expand Down Expand Up @@ -3197,7 +3197,7 @@ function createConnectionError(req, status) {
details = localAddress + ":" + localPort;
}

const ex = new ExceptionWithHostPort(status, "connect", req.address, req.port);
const ex = new ExceptionWithHostPort(status, "connect", req.address, req.port, details);
if (details) {
ex.localAddress = req.localAddress;
ex.localPort = req.localPort;
Expand Down
6 changes: 5 additions & 1 deletion src/js/node/v8.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// This is a stub! None of this is actually implemented yet.
const { hideFromStack, throwNotImplemented } = require("internal/shared");
const { validateString } = require("internal/validators");
const jsc: typeof import("bun:jsc") = require("bun:jsc");

function notimpl(message) {
Expand Down Expand Up @@ -91,7 +92,10 @@ function getHeapSpaceStatistics() {
function getHeapCodeStatistics() {
notimpl("getHeapCodeStatistics");
}
function setFlagsFromString() {
function setFlagsFromString(flags) {
// Validate before reporting the gap: node rejects a non-string argument
// regardless of whether the flag itself can be applied.
validateString(flags, "flags");
notimpl("setFlagsFromString");
}
function deserialize(value) {
Expand Down
23 changes: 23 additions & 0 deletions test/js/node/test/parallel/test-console-tty-colors-per-stream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';
require('../common');
const { Console } = require('console');
const { PassThrough } = require('stream');
const assert = require('assert');

const stdout = new PassThrough().setEncoding('utf8');
const stderr = new PassThrough().setEncoding('utf8');

const console = new Console({
stdout,
stderr,
inspectOptions: new Map([
[stdout, { colors: true }],
[stderr, { colors: false }],
]),
});

console.log('Hello', 42);
console.warn('Hello', 42);

assert.strictEqual(stdout.read(), 'Hello \x1B[33m42\x1B[39m\n');
assert.strictEqual(stderr.read(), 'Hello 42\n');
16 changes: 16 additions & 0 deletions test/js/node/test/parallel/test-v8-flag-type-check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const v8 = require('v8');

[1, undefined].forEach((value) => {
assert.throws(
() => v8.setFlagsFromString(value),
{
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
message: 'The "flags" argument must be of type string.' +
common.invalidArgTypeHelper(value)
}
);
});
46 changes: 46 additions & 0 deletions test/js/node/test/sequential/test-net-connect-local-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');

// EADDRINUSE is expected to occur on FreeBSD
// Ref: https://github.com/nodejs/node/issues/13055
const expectedErrorCodes = ['ECONNREFUSED', 'EADDRINUSE'];

const optionsIPv4 = {
port: common.PORT,
family: 4,
localPort: common.PORT + 1,
localAddress: common.localhostIPv4,
};

const optionsIPv6 = {
host: '::1',
family: 6,
port: common.PORT + 2,
localPort: common.PORT + 3,
localAddress: '::1',
};

function onError(err, options) {
assert.ok(expectedErrorCodes.includes(err.code));
assert.strictEqual(err.syscall, 'connect');
assert.strictEqual(err.localPort, options.localPort);
assert.strictEqual(err.localAddress, options.localAddress);
assert.strictEqual(
err.message,
`connect ${err.code} ${err.address}:${err.port} ` +
`- Local (${err.localAddress}:${err.localPort})`
);
}

const clientIPv4 = net.connect(optionsIPv4);
clientIPv4.on('error', common.mustCall((err) => onError(err, optionsIPv4)));

if (!common.hasIPv6) {
common.printSkipMessage('ipv6 part of test, no IPv6 support');
return;
}

const clientIPv6 = net.connect(optionsIPv6);
clientIPv6.on('error', common.mustCall((err) => onError(err, optionsIPv6)));
Loading