@planningcenter/chat-react-native 3.38.0-rc.6 → 3.38.0-rc.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -13,7 +13,7 @@ export async function instrumentedFetch(url, init) {
|
|
|
13
13
|
return response;
|
|
14
14
|
}
|
|
15
15
|
catch (networkError) {
|
|
16
|
-
|
|
16
|
+
warnNetworkError(networkError, method, url);
|
|
17
17
|
throw networkError;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -34,11 +34,9 @@ function reportHttpError(response, method, url) {
|
|
|
34
34
|
},
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function warnNetworkError(networkError, method, url) {
|
|
38
38
|
const path = templatePath(url);
|
|
39
|
-
|
|
40
|
-
error.name = 'NetworkError';
|
|
41
|
-
Log.reportError(error, {
|
|
39
|
+
console.warn(`Network failure ${method} ${path}: ${networkError.message}`, {
|
|
42
40
|
scope: 'http',
|
|
43
41
|
tags: {
|
|
44
42
|
...SHARED_TAGS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumented_fetch.js","sourceRoot":"","sources":["../../../src/utils/client/instrumented_fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAA;AAEtD,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,mBAAmB;CACpB,CAAA;AAEV,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAExC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,IAAiB;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACvC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;QACxD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,OAAO,YAAY,EAAE,CAAC;QACtB,
|
|
1
|
+
{"version":3,"file":"instrumented_fetch.js","sourceRoot":"","sources":["../../../src/utils/client/instrumented_fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAA;AAEtD,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,mBAAmB;CACpB,CAAA;AAEV,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAExC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,IAAiB;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACvC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;QACxD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,OAAO,YAAY,EAAE,CAAC;QACtB,gBAAgB,CAAC,YAAqB,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;QACpD,MAAM,YAAY,CAAA;IACpB,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,QAAkB,EAAE,MAAc,EAAE,GAAW;IACtE,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAA;IAC3B,IAAI,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAM;IAE7C,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IAC9B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC,CAAA;IAC3D,KAAK,CAAC,IAAI,GAAG,YAAY,MAAM,EAAE,CAAA;IAEjC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE;QACrB,KAAK,EAAE,MAAM;QACb,IAAI,EAAE;YACJ,GAAG,WAAW;YACd,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;YAC7B,aAAa,EAAE,MAAM;YACrB,WAAW,EAAE,IAAI;SAClB;KACF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,YAAmB,EAAE,MAAc,EAAE,GAAW;IACxE,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IAC9B,OAAO,CAAC,IAAI,CAAC,mBAAmB,MAAM,IAAI,IAAI,KAAK,YAAY,CAAC,OAAO,EAAE,EAAE;QACzE,KAAK,EAAE,MAAM;QACb,IAAI,EAAE;YACJ,GAAG,WAAW;YACd,aAAa,EAAE,MAAM;YACrB,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,SAAS;SACxB;KACF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,IAAY,CAAA;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,GAAG,CAAA;IACZ,CAAC;IAED,OAAO,IAAI;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;SACzD,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC","sourcesContent":["import { Log } from '../native_adapters/configuration'\n\nconst SHARED_TAGS = {\n team: 'chat',\n package: 'chat-react-native',\n} as const\n\nconst SKIPPED_STATUSES = [401, 403, 404]\n\nexport async function instrumentedFetch(url: string, init: RequestInit): Promise<Response> {\n const method = init.method ?? 'GET'\n try {\n const response = await fetch(url, init)\n if (!response.ok) reportHttpError(response, method, url)\n return response\n } catch (networkError) {\n warnNetworkError(networkError as Error, method, url)\n throw networkError\n }\n}\n\nfunction reportHttpError(response: Response, method: string, url: string) {\n const { status } = response\n if (SKIPPED_STATUSES.includes(status)) return\n\n const path = templatePath(url)\n const error = new Error(`HTTP ${status} ${method} ${path}`)\n error.name = `HTTPError${status}`\n\n Log.reportError(error, {\n scope: 'http',\n tags: {\n ...SHARED_TAGS,\n 'http.status': String(status),\n 'http.method': method,\n 'http.path': path,\n },\n })\n}\n\nfunction warnNetworkError(networkError: Error, method: string, url: string) {\n const path = templatePath(url)\n console.warn(`Network failure ${method} ${path}: ${networkError.message}`, {\n scope: 'http',\n tags: {\n ...SHARED_TAGS,\n 'http.method': method,\n 'http.path': path,\n 'http.error': 'network',\n },\n })\n}\n\nfunction templatePath(url: string): string {\n let path: string\n try {\n path = new URL(url).pathname\n } catch {\n path = url\n }\n\n return path\n .split('/')\n .map(segment => (/^\\d+$/.test(segment) ? ':id' : segment))\n .join('/')\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.38.0-rc.
|
|
3
|
+
"version": "3.38.0-rc.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "./src/index.tsx",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
|
28
28
|
"@fortawesome/react-native-fontawesome": "^0.3.2",
|
|
29
|
-
"@planningcenter/emoji-keyboard": "3.38.0-rc.
|
|
29
|
+
"@planningcenter/emoji-keyboard": "3.38.0-rc.7",
|
|
30
30
|
"lodash-inflection": "^1.5.0",
|
|
31
31
|
"react-compiler-runtime": "^1.0.0"
|
|
32
32
|
},
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"react-native-url-polyfill": "^2.0.0",
|
|
73
73
|
"typescript": "~5.9.2"
|
|
74
74
|
},
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "ea5571bc4ce4af6cebf789ea2b25493267eb1899"
|
|
76
76
|
}
|
|
@@ -5,15 +5,18 @@ const buildResponse = (status: number) => new Response('', { status })
|
|
|
5
5
|
|
|
6
6
|
describe('instrumentedFetch', () => {
|
|
7
7
|
let reportError: jest.SpyInstance
|
|
8
|
+
let warnSpy: jest.SpyInstance
|
|
8
9
|
let fetchSpy: jest.SpyInstance
|
|
9
10
|
|
|
10
11
|
beforeEach(() => {
|
|
11
12
|
reportError = jest.spyOn(Log, 'reportError').mockImplementation(() => {})
|
|
13
|
+
warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
12
14
|
fetchSpy = jest.spyOn(globalThis, 'fetch')
|
|
13
15
|
})
|
|
14
16
|
|
|
15
17
|
afterEach(() => {
|
|
16
18
|
reportError.mockRestore()
|
|
19
|
+
warnSpy.mockRestore()
|
|
17
20
|
fetchSpy.mockRestore()
|
|
18
21
|
})
|
|
19
22
|
|
|
@@ -27,6 +30,7 @@ describe('instrumentedFetch', () => {
|
|
|
27
30
|
|
|
28
31
|
expect(result).toBe(response)
|
|
29
32
|
expect(reportError).not.toHaveBeenCalled()
|
|
33
|
+
expect(warnSpy).not.toHaveBeenCalled()
|
|
30
34
|
})
|
|
31
35
|
|
|
32
36
|
it.each([400, 422, 500])(
|
|
@@ -63,7 +67,7 @@ describe('instrumentedFetch', () => {
|
|
|
63
67
|
expect(reportError).not.toHaveBeenCalled()
|
|
64
68
|
})
|
|
65
69
|
|
|
66
|
-
it('
|
|
70
|
+
it('warns on network failures instead of reporting them', async () => {
|
|
67
71
|
const networkError = new TypeError('Network request failed')
|
|
68
72
|
fetchSpy.mockRejectedValueOnce(networkError)
|
|
69
73
|
|
|
@@ -71,10 +75,10 @@ describe('instrumentedFetch', () => {
|
|
|
71
75
|
instrumentedFetch('https://api.example.com/conversations/123', { method: 'GET' })
|
|
72
76
|
).rejects.toBe(networkError)
|
|
73
77
|
|
|
74
|
-
expect(reportError).
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
expect(
|
|
78
|
+
expect(reportError).not.toHaveBeenCalled()
|
|
79
|
+
expect(warnSpy).toHaveBeenCalledTimes(1)
|
|
80
|
+
const [message, context] = warnSpy.mock.calls[0]
|
|
81
|
+
expect(message).toContain('Network failure GET /conversations/:id')
|
|
78
82
|
expect(context.tags).toMatchObject({
|
|
79
83
|
'http.method': 'GET',
|
|
80
84
|
'http.path': '/conversations/:id',
|
|
@@ -14,7 +14,7 @@ export async function instrumentedFetch(url: string, init: RequestInit): Promise
|
|
|
14
14
|
if (!response.ok) reportHttpError(response, method, url)
|
|
15
15
|
return response
|
|
16
16
|
} catch (networkError) {
|
|
17
|
-
|
|
17
|
+
warnNetworkError(networkError as Error, method, url)
|
|
18
18
|
throw networkError
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -38,12 +38,9 @@ function reportHttpError(response: Response, method: string, url: string) {
|
|
|
38
38
|
})
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function
|
|
41
|
+
function warnNetworkError(networkError: Error, method: string, url: string) {
|
|
42
42
|
const path = templatePath(url)
|
|
43
|
-
|
|
44
|
-
error.name = 'NetworkError'
|
|
45
|
-
|
|
46
|
-
Log.reportError(error, {
|
|
43
|
+
console.warn(`Network failure ${method} ${path}: ${networkError.message}`, {
|
|
47
44
|
scope: 'http',
|
|
48
45
|
tags: {
|
|
49
46
|
...SHARED_TAGS,
|