Skip to content

Commit

Permalink
Add error repacking
Browse files Browse the repository at this point in the history
  • Loading branch information
Apollon77 committed Dec 28, 2024
1 parent 0a520fb commit 7508ff6
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
31 changes: 27 additions & 4 deletions packages/general/src/util/Error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
*/

import type { Constructable } from "./Construction.js";
import { ClassExtends } from "./Type.js";

/** If the cause has a "message" field, treat as an Error */
function considerAsError(error: unknown): error is Error {
return (error as Error).message !== undefined;
}

/**
* Ensure that a cause is an error object.
*
* We consider anything with a "message" property to be a reasonable error object.
*/
export function errorOf(cause: unknown): Error {
// If the cause is an Constructable, use its construction error
// If the cause is a Constructable, use its construction error
if ((cause as Constructable)?.construction?.error) {
cause = (cause as Constructable)?.construction.error;
}
Expand All @@ -22,11 +28,28 @@ export function errorOf(cause: unknown): Error {
return Error("Unknown error");
}

// If the cause has a "message" field, treat as an Error
if ((cause as Error).message !== undefined) {
return cause as Error;
if (considerAsError(cause)) {
return cause;
}

// Otherwise create a new error using the original cause as the message
return new Error(cause.toString());
}

/**
* Repacks an error object as a different error class.
* The error stack is copied over from the original error instance
*/
export function repackErrorAs(error: unknown, repackAsErrorClass: ClassExtends<Error>) {
if (error instanceof repackAsErrorClass) {
return error;
}

if (considerAsError(error)) {
const repackedError = new repackAsErrorClass(error.message);
repackedError.stack = error.stack;
return repackedError;
}

throw new TypeError("Cannot repackage non-Error object");
}
10 changes: 5 additions & 5 deletions packages/nodejs/src/net/NodeJsUdpChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Logger,
MAX_UDP_MESSAGE_SIZE,
NetworkError,
repackErrorAs,
UdpChannel,
UdpChannelOptions,
} from "#general";
Expand Down Expand Up @@ -136,17 +137,16 @@ export class NodeJsUdpChannel implements UdpChannel {
this.socket.send(data, port, host, error => {
if (error !== null) {
const netError =
error instanceof Error && "code" in error && error.code === "EHOSTUNREACH"
? new RetransmissionLimitReachedError(error.message)
: new NetworkError(error.message);
netError.stack = error.stack;
"code" in error && error.code === "EHOSTUNREACH"
? repackErrorAs(error, RetransmissionLimitReachedError)
: repackErrorAs(error, NetworkError);
reject(netError);
return;
}
resolve();
});
} catch (error) {
reject(new NetworkError((error as Error).message));
reject(repackErrorAs(error, NetworkError));
}
});
}
Expand Down
6 changes: 2 additions & 4 deletions packages/protocol/src/peer/ControllerCommissioningFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { GeneralCommissioning } from "#clusters/general-commissioning";
import { NetworkCommissioning } from "#clusters/network-commissioning";
import { OperationalCredentials } from "#clusters/operational-credentials";
import { TimeSynchronizationCluster } from "#clusters/time-synchronization";
import { Bytes, ChannelType, Crypto, Logger, MatterError, Time, UnexpectedDataError } from "#general";
import { Bytes, ChannelType, Crypto, Logger, MatterError, Time, UnexpectedDataError, repackErrorAs } from "#general";
import {
ClusterId,
ClusterType,
Expand Down Expand Up @@ -250,9 +250,7 @@ export class ControllerCommissioningFlow {
StatusResponseError.accept(error);

// Convert error
const commError = new CommissioningError(error.message);
commError.stack = error.stack;
throw commError;
throw repackErrorAs(error, CommissioningError);
} else {
throw error;
}
Expand Down
5 changes: 2 additions & 3 deletions packages/react-native/src/net/UdpChannelReactNative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Logger,
MAX_UDP_MESSAGE_SIZE,
NetworkError,
repackErrorAs,
UdpChannel,
UdpChannelOptions,
} from "#general";
Expand Down Expand Up @@ -179,9 +180,7 @@ export class UdpChannelReactNative implements UdpChannel {
return new Promise<void>((resolve, reject) => {
this.socket.send(data, port, host, error => {
if (error !== null) {
const netError = new NetworkError(error.message);
netError.stack = error.stack;
reject(netError);
reject(repackErrorAs(error, NetworkError));
return;
}
resolve();
Expand Down

0 comments on commit 7508ff6

Please sign in to comment.