diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a0aa11ad..18536a814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,9 @@ Breaking changes: * `BaseComponent`: Renamed `CONFIG_CLASS` to `configClass`. Other notable changes: -* None. +* `loggy-intf`: + * `LoggyIntf`: New static methods `expectInstance()` and + `expectInstanceOrNull()`, to avoid more ad-hoc checks. ### v0.8.5 -- 2024-12-06 diff --git a/src/loggy-intf/export/IntfLogger.js b/src/loggy-intf/export/IntfLogger.js index 18b45cd56..7e7f6f9fc 100644 --- a/src/loggy-intf/export/IntfLogger.js +++ b/src/loggy-intf/export/IntfLogger.js @@ -1,7 +1,7 @@ // Copyright 2022-2024 the Lactoserv Authors (Dan Bornstein et alia). // SPDX-License-Identifier: Apache-2.0 -import { Methods } from '@this/typey'; +import { AskIf, Methods } from '@this/typey'; import { IntfLoggingEnvironment } from '#x/IntfLoggingEnvironment'; import { LogPayload } from '#x/LogPayload'; @@ -79,6 +79,47 @@ export class IntfLogger { return Methods.abstract(); } + + // + // Static members + // + + /** + * Returns the given value if it is an instance of this interface. Throws an + * error if not. + * + * **Note:** Because of JavaScript's loosey-goosey nature, this method is, as + * a practical matter, overly accepting of values as instances. + * + * @param {*} logger (Alleged) logger instance. + * @returns {IntfLogger} `logger` if it is a logger. + * @throws {Error} Thrown if `logger` is not actually a logger. + */ + static expectInstance(logger) { + if (logger instanceof IntfLogger) { + return logger; + } else if (AskIf.callableFunction(logger) && logger.$env) { + return logger; + } + + throw new Error(`Not a logger: ${logger}`); + } + + /** + * Returns the given value if it is an instance of this interface or is + * `null`. Throws an error if not either. + * + * **Note:** Because of JavaScript's loosey-goosey nature, this method is, as + * a practical matter, overly accepting of values as instances. + * + * @param {*} logger (Alleged) logger instance. + * @returns {?IntfLogger} `logger` if it is a logger or `null`. + * @throws {Error} Thrown if `logger` is not actually a logger or `null`. + */ + static expectInstanceOrNull(logger) { + return (logger === null) ? null : this.expectInstance(logger); + } + /** * Metainformation about a logger. Instances of this interface are returned * when accessing the property `$meta` on logger instances. diff --git a/src/metacomp/export/LimitedLoader.js b/src/metacomp/export/LimitedLoader.js index f66b07031..d76cb3ee7 100644 --- a/src/metacomp/export/LimitedLoader.js +++ b/src/metacomp/export/LimitedLoader.js @@ -71,7 +71,7 @@ export class LimitedLoader { */ constructor(context = null, logger = null) { this.#context = context; - this.#logger = logger; + this.#logger = IntfLogger.expectInstanceOrNull(logger); if (context && !vm.isContext(context)) { vm.createContext(context); diff --git a/src/net-protocol/export/ProtocolWrangler.js b/src/net-protocol/export/ProtocolWrangler.js index f09e96652..a9fe1d3fd 100644 --- a/src/net-protocol/export/ProtocolWrangler.js +++ b/src/net-protocol/export/ProtocolWrangler.js @@ -181,7 +181,7 @@ export class ProtocolWrangler { * logging. */ async init(logger) { - this.#logger = logger; + this.#logger = IntfLogger.expectInstanceOrNull(logger); // Confusion alert!: This is not the same as the `requestLogger` (a "request // logger") per se) passed in as an option. This is the sub-logger of the diff --git a/src/net-protocol/private/AsyncServerSocket.js b/src/net-protocol/private/AsyncServerSocket.js index c6a320f91..5b770dfe5 100644 --- a/src/net-protocol/private/AsyncServerSocket.js +++ b/src/net-protocol/private/AsyncServerSocket.js @@ -76,7 +76,7 @@ export class AsyncServerSocket { // Note: `interface` is a reserved word. this.#interface = MustBe.instanceOf(iface, InterfaceAddress); this.#protocol = MustBe.string(protocol); - this.#logger = logger; + this.#logger = IntfLogger.expectInstanceOrNull(logger); } /** diff --git a/src/net-protocol/private/WranglerContext.js b/src/net-protocol/private/WranglerContext.js index 65229e985..cb7862356 100644 --- a/src/net-protocol/private/WranglerContext.js +++ b/src/net-protocol/private/WranglerContext.js @@ -267,8 +267,8 @@ export class WranglerContext { ctx.#socket = socket; if (logger) { - ctx.#connectionLogger = logger; - ctx.#connectionId = logger.$meta.lastContext; + ctx.#connectionLogger = IntfLogger.expectInstanceOrNull(logger); + ctx.#connectionId = logger?.$meta.lastContext ?? null; } ctx.bind(socket); diff --git a/src/net-util/export/DispatchInfo.js b/src/net-util/export/DispatchInfo.js index b2c79fc6c..d4ca6664e 100644 --- a/src/net-util/export/DispatchInfo.js +++ b/src/net-util/export/DispatchInfo.js @@ -57,7 +57,7 @@ export class DispatchInfo extends IntfDeconstructable { this.#base = MustBe.instanceOf(base, PathKey); this.#extra = MustBe.instanceOf(extra, PathKey); - this.#logger = (logger === null) ? null : MustBe.callableFunction(logger); + this.#logger = IntfLogger.expectInstanceOrNull(logger); } /** @override */ diff --git a/src/webapp-core/export/HostManager.js b/src/webapp-core/export/HostManager.js index 57bd08d45..bc7082a43 100644 --- a/src/webapp-core/export/HostManager.js +++ b/src/webapp-core/export/HostManager.js @@ -130,7 +130,7 @@ export class HostManager extends TemplAggregateComponent('HostAggregate', BaseCo * @param {?IntfLogger} logger Logger to use, if any. */ constructor(logger) { - this.#logger = logger; + this.#logger = IntfLogger.expectInstanceOrNull(logger); } /**