1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-09 07:39:15 -05:00

fix(std): Use Deno.errors where possible. (#4356)

This commit is contained in:
Oliver Lenehan 2020-03-14 12:40:13 +11:00 committed by GitHub
parent aab1acaed1
commit 0f6acf2753
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 71 additions and 86 deletions

View file

@ -1,7 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { UnexpectedEOFError } from "../io/bufio.ts";
type RawBaseTypes = "int8" | "int16" | "int32" | "uint8" | "uint16" | "uint32"; type RawBaseTypes = "int8" | "int16" | "int32" | "uint8" | "uint16" | "uint32";
type RawNumberTypes = RawBaseTypes | "float32" | "float64"; type RawNumberTypes = RawBaseTypes | "float32" | "float64";
type RawBigTypes = RawBaseTypes | "int64" | "uint64"; type RawBigTypes = RawBaseTypes | "int64" | "uint64";
@ -46,14 +44,14 @@ export function sizeof(dataType: RawTypes): number {
/** Reads `n` bytes from `r`. /** Reads `n` bytes from `r`.
* *
* Returns it in a `Uint8Array`, or throws `UnexpectedEOFError` if `n` bytes cannot be read. */ * Returns it in a `Uint8Array`, or throws `Deno.errors.UnexpectedEof` if `n` bytes cannot be read. */
export async function getNBytes( export async function getNBytes(
r: Deno.Reader, r: Deno.Reader,
n: number n: number
): Promise<Uint8Array> { ): Promise<Uint8Array> {
const scratch = new Uint8Array(n); const scratch = new Uint8Array(n);
const nRead = await r.read(scratch); const nRead = await r.read(scratch);
if (nRead === Deno.EOF || nRead < n) throw new UnexpectedEOFError(); if (nRead === Deno.EOF || nRead < n) throw new Deno.errors.UnexpectedEof();
return scratch; return scratch;
} }
@ -199,7 +197,7 @@ export function putVarbig(
/** Reads a number from `r`, comsuming `sizeof(o.dataType)` bytes. Data-type defaults to `int32`. /** Reads a number from `r`, comsuming `sizeof(o.dataType)` bytes. Data-type defaults to `int32`.
* *
* Returns it as `number`, or throws `UnexpectedEOFError` if not enough bytes can be read. */ * Returns it as `number`, or throws `Deno.errors.UnexpectedEof` if not enough bytes can be read. */
export async function readVarnum( export async function readVarnum(
r: Deno.Reader, r: Deno.Reader,
o: VarnumOptions = {} o: VarnumOptions = {}
@ -211,7 +209,7 @@ export async function readVarnum(
/** Reads an integer from `r`, comsuming `sizeof(o.dataType)` bytes. Data-type defaults to `int64`. /** Reads an integer from `r`, comsuming `sizeof(o.dataType)` bytes. Data-type defaults to `int64`.
* *
* Returns it as `bigint`, or throws `UnexpectedEOFError` if not enough bytes can be read. */ * Returns it as `bigint`, or throws `Deno.errors.UnexpectedEof` if not enough bytes can be read. */
export async function readVarbig( export async function readVarbig(
r: Deno.Reader, r: Deno.Reader,
o: VarbigOptions = {} o: VarbigOptions = {}

View file

@ -1,7 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { assertEquals, assertThrowsAsync } from "../testing/asserts.ts"; import { assertEquals, assertThrowsAsync } from "../testing/asserts.ts";
import { UnexpectedEOFError } from "../io/bufio.ts";
import { import {
getNBytes, getNBytes,
putVarbig, putVarbig,
@ -27,7 +26,7 @@ Deno.test(async function testGetNBytesThrows(): Promise<void> {
const buff = new Deno.Buffer(data.buffer); const buff = new Deno.Buffer(data.buffer);
assertThrowsAsync(async () => { assertThrowsAsync(async () => {
await getNBytes(buff, 8); await getNBytes(buff, 8);
}, UnexpectedEOFError); }, Deno.errors.UnexpectedEof);
}); });
Deno.test(async function testPutVarbig(): Promise<void> { Deno.test(async function testPutVarbig(): Promise<void> {

View file

@ -1,4 +1,4 @@
import { BufReader, UnexpectedEOFError, BufWriter } from "../io/bufio.ts"; import { BufReader, BufWriter } from "../io/bufio.ts";
import { TextProtoReader } from "../textproto/mod.ts"; import { TextProtoReader } from "../textproto/mod.ts";
import { assert } from "../testing/asserts.ts"; import { assert } from "../testing/asserts.ts";
import { encoder } from "../strings/mod.ts"; import { encoder } from "../strings/mod.ts";
@ -57,13 +57,13 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
chunks.shift(); chunks.shift();
// Consume \r\n; // Consume \r\n;
if ((await tp.readLine()) === Deno.EOF) { if ((await tp.readLine()) === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
} }
return readLength; return readLength;
} }
const line = await tp.readLine(); const line = await tp.readLine();
if (line === Deno.EOF) throw new UnexpectedEOFError(); if (line === Deno.EOF) throw new Deno.errors.UnexpectedEof();
// TODO: handle chunk extension // TODO: handle chunk extension
const [chunkSizeString] = line.split(";"); const [chunkSizeString] = line.split(";");
const chunkSize = parseInt(chunkSizeString, 16); const chunkSize = parseInt(chunkSizeString, 16);
@ -74,12 +74,12 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
if (chunkSize > buf.byteLength) { if (chunkSize > buf.byteLength) {
let eof = await r.readFull(buf); let eof = await r.readFull(buf);
if (eof === Deno.EOF) { if (eof === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
const restChunk = new Uint8Array(chunkSize - buf.byteLength); const restChunk = new Uint8Array(chunkSize - buf.byteLength);
eof = await r.readFull(restChunk); eof = await r.readFull(restChunk);
if (eof === Deno.EOF) { if (eof === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} else { } else {
chunks.push({ chunks.push({
offset: 0, offset: 0,
@ -91,11 +91,11 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
const bufToFill = buf.subarray(0, chunkSize); const bufToFill = buf.subarray(0, chunkSize);
const eof = await r.readFull(bufToFill); const eof = await r.readFull(bufToFill);
if (eof === Deno.EOF) { if (eof === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
// Consume \r\n // Consume \r\n
if ((await tp.readLine()) === Deno.EOF) { if ((await tp.readLine()) === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
return chunkSize; return chunkSize;
} }
@ -103,7 +103,7 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader {
assert(chunkSize === 0); assert(chunkSize === 0);
// Consume \r\n // Consume \r\n
if ((await r.readLine()) === Deno.EOF) { if ((await r.readLine()) === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
await readTrailers(h, r); await readTrailers(h, r);
finished = true; finished = true;
@ -348,7 +348,7 @@ export async function readRequest(
const firstLine = await tp.readLine(); // e.g. GET /index.html HTTP/1.0 const firstLine = await tp.readLine(); // e.g. GET /index.html HTTP/1.0
if (firstLine === Deno.EOF) return Deno.EOF; if (firstLine === Deno.EOF) return Deno.EOF;
const headers = await tp.readMIMEHeader(); const headers = await tp.readMIMEHeader();
if (headers === Deno.EOF) throw new UnexpectedEOFError(); if (headers === Deno.EOF) throw new Deno.errors.UnexpectedEof();
const req = new ServerRequest(); const req = new ServerRequest();
req.conn = conn; req.conn = conn;

View file

@ -15,7 +15,7 @@ import {
writeResponse writeResponse
} from "./io.ts"; } from "./io.ts";
import { encode, decode } from "../strings/mod.ts"; import { encode, decode } from "../strings/mod.ts";
import { BufReader, UnexpectedEOFError, ReadLineResult } from "../io/bufio.ts"; import { BufReader, ReadLineResult } from "../io/bufio.ts";
import { chunkedBodyReader } from "./io.ts"; import { chunkedBodyReader } from "./io.ts";
import { ServerRequest, Response } from "./server.ts"; import { ServerRequest, Response } from "./server.ts";
import { StringReader } from "../io/readers.ts"; import { StringReader } from "../io/readers.ts";
@ -369,7 +369,7 @@ test(async function testReadRequestError(): Promise<void> {
}, },
{ {
in: "GET / HTTP/1.1\r\nheader:foo\r\n", in: "GET / HTTP/1.1\r\nheader:foo\r\n",
err: UnexpectedEOFError err: Deno.errors.UnexpectedEof
}, },
{ in: "", err: Deno.EOF }, { in: "", err: Deno.EOF },
{ {
@ -437,7 +437,7 @@ test(async function testReadRequestError(): Promise<void> {
} else if (typeof test.err === "string") { } else if (typeof test.err === "string") {
assertEquals(err.message, test.err); assertEquals(err.message, test.err);
} else if (test.err) { } else if (test.err) {
assert(err instanceof (test.err as typeof UnexpectedEOFError)); assert(err instanceof (test.err as typeof Deno.errors.UnexpectedEof));
} else { } else {
assert(req instanceof ServerRequest); assert(req instanceof ServerRequest);
assert(test.headers); assert(test.headers);

View file

@ -21,11 +21,11 @@ export class BufferFullError extends Error {
} }
} }
export class UnexpectedEOFError extends Error { export class PartialReadError extends Deno.errors.UnexpectedEof {
name = "UnexpectedEOFError"; name = "PartialReadError";
partial?: Uint8Array; partial?: Uint8Array;
constructor() { constructor() {
super("Unexpected EOF"); super("Encountered UnexpectedEof, data only partially read");
} }
} }
@ -178,7 +178,7 @@ export class BufReader implements Reader {
if (bytesRead === 0) { if (bytesRead === 0) {
return Deno.EOF; return Deno.EOF;
} else { } else {
throw new UnexpectedEOFError(); throw new PartialReadError();
} }
} }
bytesRead += rr; bytesRead += rr;

View file

@ -15,7 +15,7 @@ import {
BufReader, BufReader,
BufWriter, BufWriter,
BufferFullError, BufferFullError,
UnexpectedEOFError, PartialReadError,
readStringDelim, readStringDelim,
readLines readLines
} from "./bufio.ts"; } from "./bufio.ts";
@ -369,9 +369,9 @@ Deno.test(async function bufReaderReadFull(): Promise<void> {
const buf = new Uint8Array(6); const buf = new Uint8Array(6);
try { try {
await bufr.readFull(buf); await bufr.readFull(buf);
fail("readFull() should throw"); fail("readFull() should throw PartialReadError");
} catch (err) { } catch (err) {
assert(err instanceof UnexpectedEOFError); assert(err instanceof PartialReadError);
assert(err.partial instanceof Uint8Array); assert(err.partial instanceof Uint8Array);
assertEquals(err.partial.length, 5); assertEquals(err.partial.length, 5);
assertEquals(dec.decode(buf.subarray(0, 5)), "World"); assertEquals(dec.decode(buf.subarray(0, 5)), "World");

View file

@ -36,14 +36,7 @@ export class HalfReader implements Reader {
} }
} }
export class ErrTimeout extends Error { /** TimeoutReader returns `Deno.errors.TimedOut` on the second read
constructor() {
super("timeout");
this.name = "ErrTimeout";
}
}
/** TimeoutReader returns ErrTimeout on the second read
* with no data. Subsequent calls to read succeed. * with no data. Subsequent calls to read succeed.
*/ */
export class TimeoutReader implements Reader { export class TimeoutReader implements Reader {
@ -53,7 +46,7 @@ export class TimeoutReader implements Reader {
async read(p: Uint8Array): Promise<number | Deno.EOF> { async read(p: Uint8Array): Promise<number | Deno.EOF> {
this.count++; this.count++;
if (this.count === 2) { if (this.count === 2) {
throw new ErrTimeout(); throw new Deno.errors.TimedOut();
} }
return this.r.read(p); return this.r.read(p);
} }

View file

@ -1,5 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { BufReader, UnexpectedEOFError } from "./bufio.ts"; import { BufReader } from "./bufio.ts";
type Reader = Deno.Reader; type Reader = Deno.Reader;
type Writer = Deno.Writer; type Writer = Deno.Writer;
import { assert } from "../testing/asserts.ts"; import { assert } from "../testing/asserts.ts";
@ -37,7 +37,7 @@ export async function readShort(buf: BufReader): Promise<number | Deno.EOF> {
const high = await buf.readByte(); const high = await buf.readByte();
if (high === Deno.EOF) return Deno.EOF; if (high === Deno.EOF) return Deno.EOF;
const low = await buf.readByte(); const low = await buf.readByte();
if (low === Deno.EOF) throw new UnexpectedEOFError(); if (low === Deno.EOF) throw new Deno.errors.UnexpectedEof();
return (high << 8) | low; return (high << 8) | low;
} }
@ -46,7 +46,7 @@ export async function readInt(buf: BufReader): Promise<number | Deno.EOF> {
const high = await readShort(buf); const high = await readShort(buf);
if (high === Deno.EOF) return Deno.EOF; if (high === Deno.EOF) return Deno.EOF;
const low = await readShort(buf); const low = await readShort(buf);
if (low === Deno.EOF) throw new UnexpectedEOFError(); if (low === Deno.EOF) throw new Deno.errors.UnexpectedEof();
return (high << 16) | low; return (high << 16) | low;
} }
@ -57,7 +57,7 @@ export async function readLong(buf: BufReader): Promise<number | Deno.EOF> {
const high = await readInt(buf); const high = await readInt(buf);
if (high === Deno.EOF) return Deno.EOF; if (high === Deno.EOF) return Deno.EOF;
const low = await readInt(buf); const low = await readInt(buf);
if (low === Deno.EOF) throw new UnexpectedEOFError(); if (low === Deno.EOF) throw new Deno.errors.UnexpectedEof();
const big = (BigInt(high) << 32n) | BigInt(low); const big = (BigInt(high) << 32n) | BigInt(low);
// We probably should provide a similar API that returns BigInt values. // We probably should provide a similar API that returns BigInt values.
if (big > MAX_SAFE_INTEGER) { if (big > MAX_SAFE_INTEGER) {

View file

@ -10,7 +10,7 @@ import { copyN } from "../io/ioutil.ts";
import { MultiReader } from "../io/readers.ts"; import { MultiReader } from "../io/readers.ts";
import { extname } from "../path/mod.ts"; import { extname } from "../path/mod.ts";
import { tempFile } from "../io/util.ts"; import { tempFile } from "../io/util.ts";
import { BufReader, BufWriter, UnexpectedEOFError } from "../io/bufio.ts"; import { BufReader, BufWriter } from "../io/bufio.ts";
import { encoder } from "../strings/mod.ts"; import { encoder } from "../strings/mod.ts";
import { assertStrictEq, assert } from "../testing/asserts.ts"; import { assertStrictEq, assert } from "../testing/asserts.ts";
import { TextProtoReader } from "../textproto/mod.ts"; import { TextProtoReader } from "../textproto/mod.ts";
@ -166,7 +166,7 @@ class PartReader implements Reader, Closer {
peekLength = max(peekLength, br.buffered()); peekLength = max(peekLength, br.buffered());
const peekBuf = await br.peek(peekLength); const peekBuf = await br.peek(peekLength);
if (peekBuf === Deno.EOF) { if (peekBuf === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
const eof = peekBuf.length < peekLength; const eof = peekBuf.length < peekLength;
this.n = scanUntilBoundary( this.n = scanUntilBoundary(
@ -352,14 +352,14 @@ export class MultipartReader {
for (;;) { for (;;) {
const line = await this.bufReader.readSlice("\n".charCodeAt(0)); const line = await this.bufReader.readSlice("\n".charCodeAt(0));
if (line === Deno.EOF) { if (line === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
if (this.isBoundaryDelimiterLine(line)) { if (this.isBoundaryDelimiterLine(line)) {
this.partsRead++; this.partsRead++;
const r = new TextProtoReader(this.bufReader); const r = new TextProtoReader(this.bufReader);
const headers = await r.readMIMEHeader(); const headers = await r.readMIMEHeader();
if (headers === Deno.EOF) { if (headers === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
const np = new PartReader(this, headers); const np = new PartReader(this, headers);
this.currentPart = np; this.currentPart = np;

View file

@ -3,7 +3,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
import { BufReader, UnexpectedEOFError } from "../io/bufio.ts"; import { BufReader } from "../io/bufio.ts";
import { charCode } from "../io/util.ts"; import { charCode } from "../io/util.ts";
const asciiDecoder = new TextDecoder(); const asciiDecoder = new TextDecoder();
@ -15,13 +15,6 @@ function str(buf: Uint8Array | null | undefined): string {
} }
} }
export class ProtocolError extends Error {
constructor(msg: string) {
super(msg);
this.name = "ProtocolError";
}
}
export function append(a: Uint8Array, b: Uint8Array): Uint8Array { export function append(a: Uint8Array, b: Uint8Array): Uint8Array {
if (a == null) { if (a == null) {
return b; return b;
@ -79,16 +72,16 @@ export class TextProtoReader {
buf = await this.r.peek(1); buf = await this.r.peek(1);
if (buf === Deno.EOF) { if (buf === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) { } else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) {
throw new ProtocolError( throw new Deno.errors.InvalidData(
`malformed MIME header initial line: ${str(line)}` `malformed MIME header initial line: ${str(line)}`
); );
} }
while (true) { while (true) {
const kv = await this.readLineSlice(); // readContinuedLineSlice const kv = await this.readLineSlice(); // readContinuedLineSlice
if (kv === Deno.EOF) throw new UnexpectedEOFError(); if (kv === Deno.EOF) throw new Deno.errors.UnexpectedEof();
if (kv.byteLength === 0) return m; if (kv.byteLength === 0) return m;
// Key ends at first colon; should not have trailing spaces // Key ends at first colon; should not have trailing spaces
@ -96,7 +89,9 @@ export class TextProtoReader {
// them if present. // them if present.
let i = kv.indexOf(charCode(":")); let i = kv.indexOf(charCode(":"));
if (i < 0) { if (i < 0) {
throw new ProtocolError(`malformed MIME header line: ${str(kv)}`); throw new Deno.errors.InvalidData(
`malformed MIME header line: ${str(kv)}`
);
} }
let endKey = i; let endKey = i;
while (endKey > 0 && kv[endKey - 1] == charCode(" ")) { while (endKey > 0 && kv[endKey - 1] == charCode(" ")) {
@ -108,7 +103,7 @@ export class TextProtoReader {
// As per RFC 7230 field-name is a token, // As per RFC 7230 field-name is a token,
// tokens consist of one or more chars. // tokens consist of one or more chars.
// We could return a ProtocolError here, // We could throw `Deno.errors.InvalidData` here,
// but better to be liberal in what we // but better to be liberal in what we
// accept, so if we get an empty key, skip it. // accept, so if we get an empty key, skip it.
if (key == "") { if (key == "") {

View file

@ -4,7 +4,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
import { BufReader } from "../io/bufio.ts"; import { BufReader } from "../io/bufio.ts";
import { TextProtoReader, ProtocolError } from "./mod.ts"; import { TextProtoReader } from "./mod.ts";
import { stringsReader } from "../io/util.ts"; import { stringsReader } from "../io/util.ts";
import { import {
assert, assert,
@ -134,7 +134,7 @@ test({
} catch (e) { } catch (e) {
err = e; err = e;
} }
assert(err instanceof ProtocolError); assert(err instanceof Deno.errors.InvalidData);
} }
}); });
@ -156,7 +156,7 @@ test({
} catch (e) { } catch (e) {
err = e; err = e;
} }
assert(err instanceof ProtocolError); assert(err instanceof Deno.errors.InvalidData);
} }
}); });

View file

@ -2,7 +2,7 @@
import { decode, encode } from "../strings/mod.ts"; import { decode, encode } from "../strings/mod.ts";
import { hasOwnProperty } from "../util/has_own_property.ts"; import { hasOwnProperty } from "../util/has_own_property.ts";
import { BufReader, BufWriter, UnexpectedEOFError } from "../io/bufio.ts"; import { BufReader, BufWriter } from "../io/bufio.ts";
import { readLong, readShort, sliceLongToBytes } from "../io/ioutil.ts"; import { readLong, readShort, sliceLongToBytes } from "../io/ioutil.ts";
import { Sha1 } from "./sha1.ts"; import { Sha1 } from "./sha1.ts";
import { writeResponse } from "../http/io.ts"; import { writeResponse } from "../http/io.ts";
@ -71,12 +71,6 @@ export function append(a: Uint8Array, b: Uint8Array): Uint8Array {
return output; return output;
} }
export class SocketClosedError extends Error {
constructor(msg = "Socket has already been closed") {
super(msg);
}
}
export interface WebSocketFrame { export interface WebSocketFrame {
isLastFrame: boolean; isLastFrame: boolean;
opcode: OpCode; opcode: OpCode;
@ -91,20 +85,20 @@ export interface WebSocket {
receive(): AsyncIterableIterator<WebSocketEvent>; receive(): AsyncIterableIterator<WebSocketEvent>;
/** /**
* @throws SocketClosedError * @throws `Deno.errors.ConnectionReset`
*/ */
send(data: WebSocketMessage): Promise<void>; send(data: WebSocketMessage): Promise<void>;
/** /**
* @param data * @param data
* @throws SocketClosedError * @throws `Deno.errors.ConnectionReset`
*/ */
ping(data?: WebSocketMessage): Promise<void>; ping(data?: WebSocketMessage): Promise<void>;
/** Close connection after sending close frame to peer. /** Close connection after sending close frame to peer.
* This is canonical way of disconnection but it may hang because of peer's response delay. * This is canonical way of disconnection but it may hang because of peer's response delay.
* Default close code is 1000 (Normal Closure) * Default close code is 1000 (Normal Closure)
* @throws SocketClosedError * @throws `Deno.errors.ConnectionReset`
*/ */
close(): Promise<void>; close(): Promise<void>;
close(code: number): Promise<void>; close(code: number): Promise<void>;
@ -164,8 +158,8 @@ export async function writeFrame(
} }
/** Read websocket frame from given BufReader /** Read websocket frame from given BufReader
* @throws UnexpectedEOFError When peer closed connection without close frame * @throws `Deno.errors.UnexpectedEof` When peer closed connection without close frame
* @throws Error Frame is invalid * @throws `Error` Frame is invalid
*/ */
export async function readFrame(buf: BufReader): Promise<WebSocketFrame> { export async function readFrame(buf: BufReader): Promise<WebSocketFrame> {
let b = assertNotEOF(await buf.readByte()); let b = assertNotEOF(await buf.readByte());
@ -318,7 +312,7 @@ class WebSocketImpl implements WebSocket {
private enqueue(frame: WebSocketFrame): Promise<void> { private enqueue(frame: WebSocketFrame): Promise<void> {
if (this._isClosed) { if (this._isClosed) {
throw new SocketClosedError(); throw new Deno.errors.ConnectionReset("Socket has already been closed");
} }
const d = deferred<void>(); const d = deferred<void>();
this.sendQueue.push({ d, frame }); this.sendQueue.push({ d, frame });
@ -397,7 +391,11 @@ class WebSocketImpl implements WebSocket {
this._isClosed = true; this._isClosed = true;
const rest = this.sendQueue; const rest = this.sendQueue;
this.sendQueue = []; this.sendQueue = [];
rest.forEach(e => e.d.reject(new SocketClosedError())); rest.forEach(e =>
e.d.reject(
new Deno.errors.ConnectionReset("Socket has already been closed")
)
);
} }
} }
} }
@ -495,7 +493,7 @@ export async function handshake(
const tpReader = new TextProtoReader(bufReader); const tpReader = new TextProtoReader(bufReader);
const statusLine = await tpReader.readLine(); const statusLine = await tpReader.readLine();
if (statusLine === Deno.EOF) { if (statusLine === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
const m = statusLine.match(/^(?<version>\S+) (?<statusCode>\S+) /); const m = statusLine.match(/^(?<version>\S+) (?<statusCode>\S+) /);
if (!m) { if (!m) {
@ -513,7 +511,7 @@ export async function handshake(
const responseHeaders = await tpReader.readMIMEHeader(); const responseHeaders = await tpReader.readMIMEHeader();
if (responseHeaders === Deno.EOF) { if (responseHeaders === Deno.EOF) {
throw new UnexpectedEOFError(); throw new Deno.errors.UnexpectedEof();
} }
const expectedSecAccept = createSecAccept(key); const expectedSecAccept = createSecAccept(key);

View file

@ -14,8 +14,7 @@ import {
readFrame, readFrame,
unmask, unmask,
writeFrame, writeFrame,
createWebSocket, createWebSocket
SocketClosedError
} from "./mod.ts"; } from "./mod.ts";
import { encode, decode } from "../strings/mod.ts"; import { encode, decode } from "../strings/mod.ts";
import Writer = Deno.Writer; import Writer = Deno.Writer;
@ -331,7 +330,7 @@ test("[ws] createSecKeyHasCorrectLength", () => {
assertEquals(atob(secKey).length, 16); assertEquals(atob(secKey).length, 16);
}); });
test("[ws] WebSocket should throw SocketClosedError when peer closed connection without close frame", async () => { test("[ws] WebSocket should throw `Deno.errors.ConnectionReset` when peer closed connection without close frame", async () => {
const buf = new Buffer(); const buf = new Buffer();
const eofReader: Deno.Reader = { const eofReader: Deno.Reader = {
async read(_: Uint8Array): Promise<number | Deno.EOF> { async read(_: Uint8Array): Promise<number | Deno.EOF> {
@ -341,12 +340,15 @@ test("[ws] WebSocket should throw SocketClosedError when peer closed connection
const conn = dummyConn(eofReader, buf); const conn = dummyConn(eofReader, buf);
const sock = createWebSocket({ conn }); const sock = createWebSocket({ conn });
sock.closeForce(); sock.closeForce();
await assertThrowsAsync(() => sock.send("hello"), SocketClosedError); await assertThrowsAsync(
await assertThrowsAsync(() => sock.ping(), SocketClosedError); () => sock.send("hello"),
await assertThrowsAsync(() => sock.close(0), SocketClosedError); Deno.errors.ConnectionReset
);
await assertThrowsAsync(() => sock.ping(), Deno.errors.ConnectionReset);
await assertThrowsAsync(() => sock.close(0), Deno.errors.ConnectionReset);
}); });
test("[ws] WebSocket shouldn't throw UnexpectedEOFError on recive()", async () => { test("[ws] WebSocket shouldn't throw `Deno.errors.UnexpectedEof` on recive()", async () => {
const buf = new Buffer(); const buf = new Buffer();
const eofReader: Deno.Reader = { const eofReader: Deno.Reader = {
async read(_: Uint8Array): Promise<number | Deno.EOF> { async read(_: Uint8Array): Promise<number | Deno.EOF> {
@ -382,8 +384,8 @@ test("[ws] WebSocket should reject sending promise when connection reset forcely
sock.closeForce(); sock.closeForce();
assertEquals(sock.isClosed, true); assertEquals(sock.isClosed, true);
const [a, b, c] = await p; const [a, b, c] = await p;
assert(a instanceof SocketClosedError); assert(a instanceof Deno.errors.ConnectionReset);
assert(b instanceof SocketClosedError); assert(b instanceof Deno.errors.ConnectionReset);
assert(c instanceof SocketClosedError); assert(c instanceof Deno.errors.ConnectionReset);
clearTimeout(timer); clearTimeout(timer);
}); });