diff --git a/package.json b/package.json index e187c6f..c75c7d7 100644 --- a/package.json +++ b/package.json @@ -63,8 +63,8 @@ "LICENSE" ], "dependencies": { - "@cacheable/net": "^2.0.8", - "cacheable": "^2.3.5", + "@cacheable/net": "^2.1.0", + "cacheable": "^2.5.0", "hookified": "^3.0.0", "pino": "^10.3.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 152403e..4dab579 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,11 +9,11 @@ importers: .: dependencies: '@cacheable/net': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.1.0 + version: 2.1.0 cacheable: - specifier: ^2.3.5 - version: 2.3.5 + specifier: ^2.5.0 + version: 2.5.0 hookified: specifier: ^3.0.0 version: 3.0.0 @@ -163,14 +163,14 @@ packages: cpu: [x64] os: [win32] - '@cacheable/memory@2.0.8': - resolution: {integrity: sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==} + '@cacheable/memory@2.2.0': + resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} - '@cacheable/net@2.0.8': - resolution: {integrity: sha512-uSRwS6krnRsOM65F1S2IlkGQA+VoxkrbrkBwmbFxDj/ihdSHtDpLMIaKguM0A++dUXTha2cY146yNOqwv8gAPQ==} + '@cacheable/net@2.1.0': + resolution: {integrity: sha512-DlLnk6EWquHuFKd7sMQop4/mKwYRxU36ZAn1JrvvJzTed8JmOGlJ6InzOXUqyXs8duP3LhmN1fNmBUwx4ChD3g==} - '@cacheable/utils@2.4.1': - resolution: {integrity: sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==} + '@cacheable/utils@2.5.0': + resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} '@emnapi/core@1.11.1': resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} @@ -885,8 +885,8 @@ packages: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} - cacheable@2.3.5: - resolution: {integrity: sha512-EQfaKe09tl615iNvq/TBRWTFf1AKJNXYQSsMx0Z3EI0nA+pVsVPS8wJhnRlkbdacKPh1d0qVIhwTc2zsQNFEEg==} + cacheable@2.5.0: + resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} camelcase-keys@6.2.2: resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} @@ -1805,21 +1805,22 @@ snapshots: '@biomejs/cli-win32-x64@2.5.3': optional: true - '@cacheable/memory@2.0.8': + '@cacheable/memory@2.2.0': dependencies: - '@cacheable/utils': 2.4.1 + '@cacheable/utils': 2.5.0 '@keyv/bigmap': 1.3.1(keyv@5.6.0) hookified: 1.15.1 keyv: 5.6.0 - '@cacheable/net@2.0.8': + '@cacheable/net@2.1.0': dependencies: - cacheable: 2.3.5 + '@cacheable/utils': 2.5.0 + cacheable: 2.5.0 hookified: 1.15.1 http-cache-semantics: 4.2.0 undici: 7.24.7 - '@cacheable/utils@2.4.1': + '@cacheable/utils@2.5.0': dependencies: hashery: 1.5.1 keyv: 5.6.0 @@ -2309,10 +2310,10 @@ snapshots: cac@7.0.0: {} - cacheable@2.3.5: + cacheable@2.5.0: dependencies: - '@cacheable/memory': 2.0.8 - '@cacheable/utils': 2.4.1 + '@cacheable/memory': 2.2.0 + '@cacheable/utils': 2.5.0 hookified: 1.15.1 keyv: 5.6.0 qified: 0.10.1 diff --git a/test/net-info.test.ts b/test/net-info.test.ts index 24a1854..7f3d146 100644 --- a/test/net-info.test.ts +++ b/test/net-info.test.ts @@ -1,5 +1,5 @@ import process from "node:process"; -import { describe, expect, test } from "vitest"; +import { describe, expect, test, vi } from "vitest"; import { ErrorMessages } from "../src/base-service.js"; import { NetInfo } from "../src/net-info.js"; @@ -155,4 +155,16 @@ describe("NetInfo", () => { expect(ipInfos).toBeDefined(); expect(ipInfos.length).toBe(0); }); + + test("should return an error result when the request throws", async () => { + const netInfo = new NetInfo({ apiKey: "test_api_key" }); + netInfo.on("error", () => {}); + // With @cacheable/net returning non-2xx responses instead of throwing, + // force a thrown error to exercise the catch path. + netInfo.get = vi.fn().mockRejectedValue(new Error("network down")); + const ipInfo = await netInfo.getIpInfo("1.1.1.1"); + expect(ipInfo).toHaveProperty("ip", "1.1.1.1"); + expect(ipInfo).toHaveProperty("type", "error"); + expect(ipInfo).toHaveProperty("errorMessage", "network down"); + }); }); diff --git a/test/toggle.test.ts b/test/toggle.test.ts index 7b091f4..a2f046d 100644 --- a/test/toggle.test.ts +++ b/test/toggle.test.ts @@ -1,5 +1,5 @@ import { Cacheable } from "cacheable"; -import { describe, expect, test } from "vitest"; +import { describe, expect, test, vi } from "vitest"; import { Toggle, type ToggleOptions } from "../src/toggle.js"; import { getRandomToggleContext, mockToggleContexts } from "./mock-contexts.js"; @@ -663,4 +663,21 @@ describe("Hyphen sdk", () => { expect(result).toBe(false); // Returns defaultValue when error occurs }); }); + + describe("fetch", () => { + test("should extract the status code from CacheableNet error messages", async () => { + const toggle = new Toggle({ horizonUrls: ["https://horizon.example"] }); + // @cacheable/net surfaces HTTP failures as errors whose message + // includes "status "; verify that code is parsed out. + toggle._net.fetch = vi + .fn() + .mockRejectedValue(new Error("Request failed with status 404")); + + await expect( + toggle.fetch("/toggle/evaluate", { key: "value" }), + ).rejects.toThrow( + "All horizon URLs failed. Last errors: HTTP 404: Request failed with status 404", + ); + }); + }); });