Skip to content

Commit 6eaba08

Browse files
authored
Refactor SignalR Transports Errors (#34766)
* Refactor SignalR Transports Errors Fixes: #34765 * PR Feedback * PR Feedback
1 parent a9a2d19 commit 6eaba08

File tree

4 files changed

+127
-47
lines changed

4 files changed

+127
-47
lines changed

src/Components/Web.JS/dist/Release/blazor.server.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Boot.Server.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ async function initializeConnection(options: CircuitStartOptions, logger: Logger
131131
} catch (ex) {
132132
unhandledError(connection, ex, logger);
133133

134-
if (ex.innerErrors && ex.innerErrors.some(e => e.errorType === 'UnsupportedTransportError' && e.transport === 'WebSockets')) {
134+
if (ex.innerErrors && ex.innerErrors.some(e => e.errorType === 'UnsupportedTransportError' && e.transport === HttpTransportType.WebSockets)) {
135135
showErrorNotification('Unable to connect, please ensure you are using an updated browser that supports WebSockets.');
136-
} else if (ex.innerErrors && ex.innerErrors.some(e => e.errorType === 'FailedToStartTransportError' && e.transport === 'WebSockets')) {
136+
} else if (ex.innerErrors && ex.innerErrors.some(e => e.errorType === 'FailedToStartTransportError' && e.transport === HttpTransportType.WebSockets)) {
137137
showErrorNotification('Unable to connect, please ensure WebSockets are available. A VPN or proxy may be blocking the connection.');
138-
} else if (ex.innerErrors && ex.innerErrors.some(e => e.errorType === 'DisabledTransportError' && e.transport === 'LongPolling')) {
138+
} else if (ex.innerErrors && ex.innerErrors.some(e => e.errorType === 'DisabledTransportError' && e.transport === HttpTransportType.LongPolling)) {
139139
logger.log(LogLevel.Error, 'Unable to initiate a SignalR connection to the server. This might be because the server is not configured to support WebSockets. To troubleshoot this, visit https://aka.ms/blazor-server-websockets-error.');
140140
showErrorNotification();
141141
} else {

src/SignalR/clients/ts/signalr/src/Errors.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
import { HttpTransportType } from "./ITransport";
5+
46
/** Error thrown when an HTTP request fails. */
57
export class HttpError extends Error {
68
// @ts-ignore: Intentionally unused.
@@ -65,3 +67,120 @@ export class AbortError extends Error {
6567
this.__proto__ = trueProto;
6668
}
6769
}
70+
71+
/** Error thrown when the selected transport is unsupported by the browser. */
72+
/** @private */
73+
export class UnsupportedTransportError extends Error {
74+
// @ts-ignore: Intentionally unused.
75+
// eslint-disable-next-line @typescript-eslint/naming-convention
76+
private __proto__: Error;
77+
78+
/** The {@link @microsoft/signalr.HttpTransportType} this error occured on. */
79+
public transport: HttpTransportType;
80+
81+
/** The type name of this error. */
82+
public errorType: string;
83+
84+
/** Constructs a new instance of {@link @microsoft/signalr.UnsupportedTransportError}.
85+
*
86+
* @param {string} message A descriptive error message.
87+
* @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occured on.
88+
*/
89+
constructor(message: string, transport: HttpTransportType) {
90+
const trueProto = new.target.prototype;
91+
super(message);
92+
this.transport = transport;
93+
this.errorType = 'UnsupportedTransportError';
94+
95+
// Workaround issue in Typescript compiler
96+
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
97+
this.__proto__ = trueProto;
98+
}
99+
}
100+
101+
/** Error thrown when the selected transport is disabled by the browser. */
102+
/** @private */
103+
export class DisabledTransportError extends Error {
104+
// @ts-ignore: Intentionally unused.
105+
// eslint-disable-next-line @typescript-eslint/naming-convention
106+
private __proto__: Error;
107+
108+
/** The {@link @microsoft/signalr.HttpTransportType} this error occured on. */
109+
public transport: HttpTransportType;
110+
111+
/** The type name of this error. */
112+
public errorType: string;
113+
114+
/** Constructs a new instance of {@link @microsoft/signalr.DisabledTransportError}.
115+
*
116+
* @param {string} message A descriptive error message.
117+
* @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occured on.
118+
*/
119+
constructor(message: string, transport: HttpTransportType) {
120+
const trueProto = new.target.prototype;
121+
super(message);
122+
this.transport = transport;
123+
this.errorType = 'DisabledTransportError';
124+
125+
// Workaround issue in Typescript compiler
126+
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
127+
this.__proto__ = trueProto;
128+
}
129+
}
130+
131+
/** Error thrown when the selected transport cannot be started. */
132+
/** @private */
133+
export class FailedToStartTransportError extends Error {
134+
// @ts-ignore: Intentionally unused.
135+
// eslint-disable-next-line @typescript-eslint/naming-convention
136+
private __proto__: Error;
137+
138+
/** The {@link @microsoft/signalr.HttpTransportType} this error occured on. */
139+
public transport: HttpTransportType;
140+
141+
/** The type name of this error. */
142+
public errorType: string;
143+
144+
/** Constructs a new instance of {@link @microsoft/signalr.FailedToStartTransportError}.
145+
*
146+
* @param {string} message A descriptive error message.
147+
* @param {HttpTransportType} transport The {@link @microsoft/signalr.HttpTransportType} this error occured on.
148+
*/
149+
constructor(message: string, transport: HttpTransportType) {
150+
const trueProto = new.target.prototype;
151+
super(message);
152+
this.transport = transport;
153+
this.errorType = 'FailedToStartTransportError';
154+
155+
// Workaround issue in Typescript compiler
156+
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
157+
this.__proto__ = trueProto;
158+
}
159+
}
160+
161+
/** Error thrown when multiple errors have occured. */
162+
/** @private */
163+
export class AggregateErrors extends Error {
164+
// @ts-ignore: Intentionally unused.
165+
// eslint-disable-next-line @typescript-eslint/naming-convention
166+
private __proto__: Error;
167+
168+
/** The collection of errors this error is aggregating. */
169+
public innerErrors: Error[];
170+
171+
/** Constructs a new instance of {@link @microsoft/signalr.AggregateErrors}.
172+
*
173+
* @param {string} message A descriptive error message.
174+
* @param {Error[]} innerErrors The collection of errors this error is aggregating.
175+
*/
176+
constructor(message: string, innerErrors: Error[]) {
177+
const trueProto = new.target.prototype;
178+
super(message);
179+
180+
this.innerErrors = innerErrors;
181+
182+
// Workaround issue in Typescript compiler
183+
// https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
184+
this.__proto__ = trueProto;
185+
}
186+
}

src/SignalR/clients/ts/signalr/src/HttpConnection.ts

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
import { DefaultHttpClient } from "./DefaultHttpClient";
5-
import { HttpError } from "./Errors";
5+
import { AggregateErrors, DisabledTransportError, FailedToStartTransportError, HttpError, UnsupportedTransportError } from "./Errors";
66
import { HeaderNames } from "./HeaderNames";
77
import { HttpClient } from "./HttpClient";
88
import { IConnection } from "./IConnection";
@@ -394,7 +394,7 @@ export class HttpConnection implements IConnection {
394394
} catch (ex) {
395395
this._logger.log(LogLevel.Error, `Failed to start the transport '${endpoint.transport}': ${ex}`);
396396
negotiate = undefined;
397-
transportExceptions.push(new FailedToStartTransportError(`${endpoint.transport} failed: ${ex}`, endpoint.transport));
397+
transportExceptions.push(new FailedToStartTransportError(`${endpoint.transport} failed: ${ex}`, HttpTransportType[endpoint.transport]));
398398

399399
if (this._connectionState !== ConnectionState.Connecting) {
400400
const message = "Failed to select transport before stop() was called.";
@@ -448,7 +448,7 @@ export class HttpConnection implements IConnection {
448448
if ((transport === HttpTransportType.WebSockets && !this._options.WebSocket) ||
449449
(transport === HttpTransportType.ServerSentEvents && !this._options.EventSource)) {
450450
this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it is not supported in your environment.'`);
451-
return new UnsupportedTransportError(`'${HttpTransportType[transport]}' is not supported in your environment.`, HttpTransportType[transport]);
451+
return new UnsupportedTransportError(`'${HttpTransportType[transport]}' is not supported in your environment.`, transport);
452452
} else {
453453
this._logger.log(LogLevel.Debug, `Selecting transport '${HttpTransportType[transport]}'.`);
454454
try {
@@ -463,7 +463,7 @@ export class HttpConnection implements IConnection {
463463
}
464464
} else {
465465
this._logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it was disabled by the client.`);
466-
return new DisabledTransportError(`'${HttpTransportType[transport]}' is disabled by the client.`, HttpTransportType[transport]);
466+
return new DisabledTransportError(`'${HttpTransportType[transport]}' is disabled by the client.`, transport);
467467
}
468468
}
469469
}
@@ -651,45 +651,6 @@ export class TransportSendQueue {
651651
}
652652
}
653653

654-
class UnsupportedTransportError extends Error {
655-
public errorType: string;
656-
public transport: string;
657-
658-
constructor(public message: string, transport: string) {
659-
super(message);
660-
this.errorType = 'UnsupportedTransportError';
661-
this.transport = transport;
662-
}
663-
}
664-
665-
class DisabledTransportError extends Error {
666-
public errorType: string;
667-
public transport: string;
668-
669-
constructor(public message: string, transport: string) {
670-
super(message);
671-
this.errorType = 'DisabledTransportError';
672-
this.transport = transport;
673-
}
674-
}
675-
676-
class FailedToStartTransportError extends Error {
677-
public errorType: string;
678-
public transport: string;
679-
680-
constructor(public message: string, transport: string) {
681-
super(message);
682-
this.errorType = 'FailedToStartTransportError';
683-
this.transport = transport;
684-
}
685-
}
686-
687-
class AggregateErrors extends Error {
688-
constructor(public message: string, public innerErrors: Error[]) {
689-
super(message);
690-
}
691-
}
692-
693654
class PromiseSource {
694655
private _resolver?: () => void;
695656
private _rejecter!: (reason?: any) => void;

0 commit comments

Comments
 (0)