signalk-server
Version:
An implementation of a [Signal K](http://signalk.org) server for boats.
95 lines • 3.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.patchAstronautLabsMdns = patchAstronautLabsMdns;
const debug_1 = require("./debug");
const debug = (0, debug_1.createDebug)('signalk-server:mdns-patch');
const MEMBERSHIP_ERROR_PREFIX = 'Fatal error: Could not add membership to interface ';
let patchApplied = false;
let activeConsoleFilterCount = 0;
let restoreConsoleError;
function isErrnoException(error) {
return error instanceof Error && 'code' in error;
}
function isIgnorableMembershipError(args) {
const [message, error] = args;
return (typeof message === 'string' &&
message.startsWith(MEMBERSHIP_ERROR_PREFIX) &&
isErrnoException(error) &&
error.code === 'EADDRINUSE');
}
function installConsoleFilter() {
activeConsoleFilterCount += 1;
if (activeConsoleFilterCount > 1) {
return;
}
const originalConsoleError = console.error;
const wrappedConsoleError = (...args) => {
if (isIgnorableMembershipError(args)) {
const address = args[0].slice(MEMBERSHIP_ERROR_PREFIX.length);
debug.enabled &&
debug(`Ignoring @astronautlabs/mdns addMembership EADDRINUSE on ${address}`);
return;
}
originalConsoleError(...args);
};
console.error = wrappedConsoleError;
restoreConsoleError = () => {
if (console.error === wrappedConsoleError) {
console.error = originalConsoleError;
}
restoreConsoleError = undefined;
};
}
function uninstallConsoleFilter() {
if (activeConsoleFilterCount === 0) {
return;
}
activeConsoleFilterCount -= 1;
if (activeConsoleFilterCount === 0) {
restoreConsoleError?.();
}
}
function patchAstronautLabsMdns() {
if (patchApplied) {
return;
}
let networkInterfaceModule;
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
networkInterfaceModule = require('@astronautlabs/mdns/dist/NetworkInterface');
}
catch (error) {
debug.enabled &&
debug(`Unable to patch @astronautlabs/mdns NetworkInterface: ${error}`);
return;
}
const prototype = networkInterfaceModule.NetworkInterface?.prototype;
const originalBindSocket = prototype?._bindSocket;
if (typeof originalBindSocket !== 'function') {
debug.enabled &&
debug('Unable to patch @astronautlabs/mdns NetworkInterface._bindSocket');
return;
}
if (originalBindSocket.__signalkPatched) {
patchApplied = true;
return;
}
const patchedBindSocket = function patchedBindSocket(...args) {
installConsoleFilter();
try {
const result = originalBindSocket.apply(this, args);
return result.finally(() => {
uninstallConsoleFilter();
});
}
catch (error) {
uninstallConsoleFilter();
throw error;
}
};
patchedBindSocket.__signalkPatched = true;
networkInterfaceModule.NetworkInterface.prototype._bindSocket =
patchedBindSocket;
patchApplied = true;
}
//# sourceMappingURL=mdnsPatch.js.map