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
4 changes: 4 additions & 0 deletions src/js/builtins.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,11 +439,13 @@ declare function $ERR_INVALID_CHAR(name, field?): TypeError;
declare function $ERR_HTTP_INVALID_HEADER_VALUE(value: string, name: string): TypeError;
declare function $ERR_HTTP_HEADERS_SENT(action: string): Error;
declare function $ERR_INVALID_PROTOCOL(proto, expected): TypeError;
declare function $ERR_INVALID_URL_SCHEME(expected: string): TypeError;
declare function $ERR_INVALID_STATE(message: string): Error;
declare function $ERR_INVALID_STATE_TypeError(message: string): TypeError;
declare function $ERR_INVALID_STATE_RangeError(message: string): RangeError;
declare function $ERR_UNESCAPED_CHARACTERS(arg): TypeError;
declare function $ERR_HTTP_INVALID_STATUS_CODE(code): RangeError;
declare function $ERR_HTTP_CONTENT_LENGTH_MISMATCH(actual: number, expected: number): Error;
declare function $ERR_UNHANDLED_ERROR(err?): Error;
declare function $ERR_BUFFER_OUT_OF_BOUNDS(name?: string): RangeError;
declare function $ERR_CHILD_PROCESS_IPC_REQUIRED(where): Error;
Expand Down Expand Up @@ -473,6 +475,7 @@ declare function $ERR_SOCKET_DGRAM_IS_CONNECTED(): Error;
declare function $ERR_SOCKET_DGRAM_NOT_CONNECTED(): Error;
declare function $ERR_SOCKET_DGRAM_NOT_RUNNING(): Error;
declare function $ERR_INVALID_CURSOR_POS(): Error;
declare function $ERR_SCRIPT_EXECUTION_INTERRUPTED(): Error;
declare function $ERR_MULTIPLE_CALLBACK(): Error;
declare function $ERR_STREAM_PREMATURE_CLOSE(): Error;
declare function $ERR_STREAM_NULL_VALUES(): TypeError;
Expand Down Expand Up @@ -512,6 +515,7 @@ declare function $ERR_HTTP2_ALTSVC_LENGTH(): TypeError;
declare function $ERR_HTTP2_PING_LENGTH(): RangeError;
declare function $ERR_HTTP2_OUT_OF_STREAMS(): Error;
declare function $ERR_HTTP_BODY_NOT_ALLOWED(): Error;
declare function $ERR_HTTP_TRAILER_INVALID(): Error;
declare function $ERR_HTTP_SOCKET_ASSIGNED(): Error;
declare function $ERR_DIR_CLOSED(): Error;
declare function $ERR_SOCKET_CONNECTION_TIMEOUT(): Error;
Expand Down
4 changes: 2 additions & 2 deletions src/js/internal/fs/streams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function ReadStream(this: FSStream, path, options): void {
this[kFs] = customFs || fs;
} else if (typeof fd === "object" && fd instanceof FileHandle) {
if (options.fs) {
throw $ERR_METHOD_NOT_IMPLEMENTED("fs.FileHandle with custom fs operations");
throw $ERR_METHOD_NOT_IMPLEMENTED("FileHandle with fs");
}
this[kFs] = fileHandleStreamFs(fd);
this.fd = fd[kFd];
Expand Down Expand Up @@ -408,7 +408,7 @@ function WriteStream(this: FSStream, path: string | null, options?: any): void {
this[kFs] = customFs || fs;
} else if (typeof fd === "object" && fd instanceof FileHandle) {
if (options.fs) {
throw $ERR_METHOD_NOT_IMPLEMENTED("fs.FileHandle with custom fs operations");
throw $ERR_METHOD_NOT_IMPLEMENTED("FileHandle with fs");
}
this[kFs] = customFs = fileHandleStreamFs(fd);
fd[kRef]();
Expand Down
2 changes: 1 addition & 1 deletion src/js/internal/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ function hasServerResponseFinished(self, chunk, callback) {
if (finished) {
err = $ERR_STREAM_WRITE_AFTER_END();
} else if (destroyed) {
err = $ERR_STREAM_DESTROYED("Stream is destroyed");
err = $ERR_STREAM_DESTROYED("write");
}

if (!destroyed) {
Expand Down
4 changes: 2 additions & 2 deletions src/js/internal/repl/node-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ function ERR_USE_AFTER_CLOSE(...args) {
function ERR_INVALID_CURSOR_POS(...args) {
return $ERR_INVALID_CURSOR_POS(...args);
}
function ERR_SCRIPT_EXECUTION_INTERRUPTED(...args) {
return $ERR_SCRIPT_EXECUTION_INTERRUPTED(...args);
function ERR_SCRIPT_EXECUTION_INTERRUPTED() {
return $ERR_SCRIPT_EXECUTION_INTERRUPTED();
}
function ERR_INVALID_STATE(...args) {
return $ERR_INVALID_STATE(...args);
Expand Down
4 changes: 2 additions & 2 deletions src/js/node/_http_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2041,7 +2041,7 @@ function _writeHead(statusCode, reason, obj, response) {
// header fields, regardless of the header fields present in the
// message, and thus cannot contain a message body or 'trailers'.
if (hasInvalidTrailer(response)) {
throw $ERR_HTTP_TRAILER_INVALID("Trailers are invalid with this transfer encoding");
throw $ERR_HTTP_TRAILER_INVALID();
}
// Headers in obj should override previous headers but still
// allow explicit duplicates. To do so, we first remove any
Expand Down Expand Up @@ -2071,7 +2071,7 @@ function _writeHead(statusCode, reason, obj, response) {
// The message is not chunk-framed, so `Trailer` is the offending header; drop it
// so a caller that swallows the throw cannot put it on the wire.
response.removeHeader("trailer");
throw $ERR_HTTP_TRAILER_INVALID("Trailers are invalid with this transfer encoding");
throw $ERR_HTTP_TRAILER_INVALID();
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/js/node/fs.promises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1146,7 +1146,7 @@ function asyncWrap(fn: any, name: string) {

if (bytesWritten === 0) {
if (++retries > 5) {
throw $ERR_OPERATION_FAILED("Operation failed: write failed after retries");
throw $ERR_OPERATION_FAILED("write failed after retries");
}
} else {
retries = 0;
Expand Down Expand Up @@ -1190,7 +1190,7 @@ function asyncWrap(fn: any, name: string) {
// Retry the writev as-is on a zero-byte write (up to 5 times)
// instead of degrading to the concat fallback below.
if (++retries > 5) {
throw $ERR_OPERATION_FAILED("Operation failed: writev failed after retries");
throw $ERR_OPERATION_FAILED("writev failed after retries");
}
continue;
}
Expand Down Expand Up @@ -1227,7 +1227,7 @@ function asyncWrap(fn: any, name: string) {
const bytesWritten = fsSync.writeSync(fd, buf, offset, length, position >= 0 ? position : null) || 0;
if (bytesWritten === 0) {
if (++retries > 5) {
throw $ERR_OPERATION_FAILED("Operation failed: write failed after retries");
throw $ERR_OPERATION_FAILED("write failed after retries");
}
} else {
retries = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/js/node/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,7 @@ function fileURLToPathBuffer(path: unknown, options?: { windows?: boolean }): Bu
}
const url = path as URL;
if (url.protocol !== "file:") {
throw $ERR_INVALID_URL_SCHEME("The URL must be of scheme file");
throw $ERR_INVALID_URL_SCHEME("file");
}
if (windows ?? process.platform === "win32") {
let pathname = url.pathname.replaceAll("/", "\\");
Expand Down
6 changes: 6 additions & 0 deletions src/jsc/bindings/ErrorCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,7 @@ static constexpr SimpleErrorMessage simpleErrorMessages[] = {
{ ErrorCode::ERR_INVALID_STATE_TypeError, 1, { "Invalid state: "_s, ""_s, ""_s } },
{ ErrorCode::ERR_INVALID_STATE_RangeError, 1, { "Invalid state: "_s, ""_s, ""_s } },
{ ErrorCode::ERR_INVALID_PROTOCOL, 2, { "Protocol \""_s, "\" not supported. Expected \""_s, "\""_s } },
{ ErrorCode::ERR_INVALID_URL_SCHEME, 1, { "The URL must be of scheme "_s, ""_s, ""_s } },
{ ErrorCode::ERR_BROTLI_INVALID_PARAM, 1, { ""_s, " is not a valid Brotli parameter"_s, ""_s } },
{ ErrorCode::ERR_BUFFER_TOO_LARGE, 1, { "Cannot create a Buffer larger than "_s, " bytes"_s, ""_s } },
{ ErrorCode::ERR_INVALID_THIS, 1, { "Value of \"this\" must be of type "_s, ""_s, ""_s } },
Expand All @@ -1913,6 +1914,7 @@ static constexpr SimpleErrorMessage simpleErrorMessages[] = {
{ ErrorCode::ERR_HTTP_HEADERS_SENT, 1, { "Cannot "_s, " headers after they are sent to the client"_s, ""_s } },
{ ErrorCode::ERR_UNESCAPED_CHARACTERS, 1, { ""_s, " contains unescaped characters"_s, ""_s } },
{ ErrorCode::ERR_HTTP_INVALID_STATUS_CODE, 1, { "Invalid status code: "_s, ""_s, ""_s } },
{ ErrorCode::ERR_HTTP_CONTENT_LENGTH_MISMATCH, 2, { "Response body's content-length of "_s, " byte(s) does not match the content-length of "_s, " byte(s) set in header"_s } },
{ ErrorCode::ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, 2, { "Invalid key object type "_s, ", expected "_s, "."_s } },
{ ErrorCode::ERR_CRYPTO_INCOMPATIBLE_KEY, 2, { "Incompatible "_s, ": "_s, ""_s } },
{ ErrorCode::ERR_CHILD_PROCESS_IPC_REQUIRED, 1, { "Forked processes must have an IPC channel, missing value 'ipc' in "_s, ""_s, ""_s } },
Expand Down Expand Up @@ -2321,6 +2323,8 @@ JSC_DEFINE_HOST_FUNCTION_WITH_ATTRIBUTES(Bun::jsFunctionMakeErrorWithCode, __att
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_SOCKET_DGRAM_NOT_RUNNING, "Not running"_s));
case ErrorCode::ERR_INVALID_CURSOR_POS:
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_INVALID_CURSOR_POS, "Cannot set cursor row without setting its column"_s));
case ErrorCode::ERR_SCRIPT_EXECUTION_INTERRUPTED:
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_SCRIPT_EXECUTION_INTERRUPTED, "Script execution was interrupted by `SIGINT`"_s));
case ErrorCode::ERR_INVALID_HANDLE_TYPE:
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_INVALID_HANDLE_TYPE, "This handle type cannot be sent"_s));
case ErrorCode::ERR_MULTIPLE_CALLBACK:
Expand Down Expand Up @@ -2426,6 +2430,8 @@ JSC_DEFINE_HOST_FUNCTION_WITH_ATTRIBUTES(Bun::jsFunctionMakeErrorWithCode, __att
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_HTTP2_GOAWAY_SESSION, "New streams cannot be created after receiving a GOAWAY"_s));
case ErrorCode::ERR_HTTP_BODY_NOT_ALLOWED:
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_HTTP_BODY_NOT_ALLOWED, "Adding content for this request method or response status is not allowed."_s));
case ErrorCode::ERR_HTTP_TRAILER_INVALID:
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_HTTP_TRAILER_INVALID, "Trailers are invalid with this transfer encoding"_s));
case ErrorCode::ERR_HTTP_SOCKET_ASSIGNED:
return JSC::JSValue::encode(createError(globalObject, ErrorCode::ERR_HTTP_SOCKET_ASSIGNED, "Socket already assigned"_s));
case ErrorCode::ERR_STREAM_RELEASE_LOCK:
Expand Down
41 changes: 28 additions & 13 deletions src/runtime/server/NodeHTTPResponse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,24 @@ fn err_throw<T>(global: &JSGlobalObject, code: ErrorCode, msg: &'static str) ->
Err(err_throw_cold(global, code, msg))
}

/// Same text as the `ERR_HTTP_CONTENT_LENGTH_MISMATCH` row of `simpleErrorMessages` in ErrorCode.cpp.
#[cold]
#[inline(never)]
fn err_throw_content_length_mismatch(
global: &JSGlobalObject,
actual: usize,
expected: u64,
) -> jsc::JsError {
global
.err(
ErrorCode::ERR_HTTP_CONTENT_LENGTH_MISMATCH,
format_args!(
"Response body's content-length of {actual} byte(s) does not match the content-length of {expected} byte(s) set in header"
),
)
.throw()
}

/// AnyResponse `is_ssl()` shim (upstream lacks this accessor).
#[inline]
fn any_response_is_ssl(r: &uws::AnyResponse) -> bool {
Expand Down Expand Up @@ -1974,20 +1992,17 @@ impl NodeHTTPResponse {
if let Some(content_length) = strict_content_length {
let bytes_written = self.bytes_written.get() + bytes.len();

if IS_END {
if bytes_written as u64 != content_length {
return err_throw(
global_object,
ErrorCode::ERR_HTTP_CONTENT_LENGTH_MISMATCH,
"Content-Length mismatch",
);
}
} else if bytes_written as u64 > content_length {
return err_throw(
let mismatch = if IS_END {
bytes_written as u64 != content_length
} else {
bytes_written as u64 > content_length
};
if mismatch {
return Err(err_throw_content_length_mismatch(
global_object,
ErrorCode::ERR_HTTP_CONTENT_LENGTH_MISMATCH,
"Content-Length mismatch",
);
bytes_written,
content_length,
));
}
self.bytes_written.set(bytes_written);
} else {
Expand Down
Loading
Loading