Skip to content

Commit 1e950d3

Browse files
bwp91claude
andcommitted
test: cover characteristic warning message for non-Error throws
Adds three Characteristic tests verifying the fix from fe8c1b3: when validateUserInput throws an object without a `message` property (e.g. a non-Error), setValue and updateValue must emit the characteristic warning with the message "Unknown error" instead of the literal string "undefined" produced by `error?.message + ""`. A real Error message is still preserved untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8ad1ab0 commit 1e950d3

2 files changed

Lines changed: 67 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ All notable changes to `@homebridge/hap-nodejs` will be documented in this file.
1919
- test: cover camera stream start TLV parsing guards
2020
- test: cover error argument in pairing debug logs
2121
- test: cover constant-time pincode comparison
22+
- test: cover characteristic warning message for non-Error throws
2223

2324
### Homebridge Dependencies
2425

src/lib/Characteristic.spec.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,4 +2199,70 @@ describe("Characteristic", () => {
21992199

22002200
});
22012201

2202+
describe("undefined string in characteristic error warnings (fix fe8c1b3a)", () => {
2203+
test("setValue should emit \"Unknown error\" when validateUserInput throws an object without a message", () => {
2204+
const characteristic = createCharacteristic(Formats.STRING);
2205+
2206+
// throw a non-Error (no `message` property) — without the fix this
2207+
// produced `error?.message + ""` === "undefined" in the warning text
2208+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2209+
jest.spyOn(characteristic as any, "validateUserInput").mockImplementation(() => {
2210+
throw {};
2211+
});
2212+
2213+
const warnings: { type: CharacteristicWarningType; message: string }[] = [];
2214+
characteristic.on(CharacteristicEventTypes.CHARACTERISTIC_WARNING, (type, message) => {
2215+
warnings.push({ type, message });
2216+
});
2217+
2218+
characteristic.setValue("anything");
2219+
2220+
const errorWarnings = warnings.filter(w => w.type === CharacteristicWarningType.ERROR_MESSAGE);
2221+
expect(errorWarnings.length).toBe(1);
2222+
expect(errorWarnings[0].message).toBe("Unknown error");
2223+
expect(errorWarnings[0].message).not.toBe("undefined");
2224+
});
2225+
2226+
test("setValue should preserve a real Error message when validateUserInput throws an Error", () => {
2227+
const characteristic = createCharacteristic(Formats.STRING);
2228+
2229+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2230+
jest.spyOn(characteristic as any, "validateUserInput").mockImplementation(() => {
2231+
throw new Error("validation failed: bad value");
2232+
});
2233+
2234+
const warnings: { type: CharacteristicWarningType; message: string }[] = [];
2235+
characteristic.on(CharacteristicEventTypes.CHARACTERISTIC_WARNING, (type, message) => {
2236+
warnings.push({ type, message });
2237+
});
2238+
2239+
characteristic.setValue("anything");
2240+
2241+
const errorWarnings = warnings.filter(w => w.type === CharacteristicWarningType.ERROR_MESSAGE);
2242+
expect(errorWarnings.length).toBe(1);
2243+
expect(errorWarnings[0].message).toBe("validation failed: bad value");
2244+
});
2245+
2246+
test("updateValue should emit \"Unknown error\" when validateUserInput throws an object without a message", () => {
2247+
const characteristic = createCharacteristic(Formats.STRING);
2248+
2249+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2250+
jest.spyOn(characteristic as any, "validateUserInput").mockImplementation(() => {
2251+
throw {};
2252+
});
2253+
2254+
const warnings: { type: CharacteristicWarningType; message: string }[] = [];
2255+
characteristic.on(CharacteristicEventTypes.CHARACTERISTIC_WARNING, (type, message) => {
2256+
warnings.push({ type, message });
2257+
});
2258+
2259+
characteristic.updateValue("anything");
2260+
2261+
const errorWarnings = warnings.filter(w => w.type === CharacteristicWarningType.ERROR_MESSAGE);
2262+
expect(errorWarnings.length).toBe(1);
2263+
expect(errorWarnings[0].message).toBe("Unknown error");
2264+
expect(errorWarnings[0].message).not.toBe("undefined");
2265+
});
2266+
});
2267+
22022268
});

0 commit comments

Comments
 (0)