feat(idnot): robust JSON handling with clear ExternalServiceError logs [skip ci]
This commit is contained in:
parent
125e9ac923
commit
fd093aec65
@ -1,7 +1,39 @@
|
||||
import fetch from 'node-fetch';
|
||||
import { IdNotUser, ECivility, EOfficeStatus, EIdnotRole } from '../../types';
|
||||
import { ExternalServiceError } from '../../types/errors';
|
||||
import { Logger } from '../../utils/logger';
|
||||
|
||||
export class IdNotService {
|
||||
private static async parseJsonOrThrow(response: Response, context: string): Promise<any> {
|
||||
const contentType = response.headers.get('content-type') || '';
|
||||
try {
|
||||
if (contentType.includes('application/json')) {
|
||||
return await (response as any).json();
|
||||
}
|
||||
const text = await (response as any).text();
|
||||
Logger.error('IdNot non-JSON response', {
|
||||
context,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
contentType,
|
||||
bodySnippet: text?.slice(0, 200)
|
||||
});
|
||||
throw new ExternalServiceError('IdNot', `Non-JSON response (${response.status} ${response.statusText}): ${text?.slice(0, 120) || 'no body'}`);
|
||||
} catch (err) {
|
||||
if (err instanceof ExternalServiceError) throw err;
|
||||
// json() may throw on invalid JSON
|
||||
const text = await (response as any).text().catch(() => undefined);
|
||||
Logger.error('IdNot JSON parse failed', {
|
||||
context,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
contentType,
|
||||
parseError: err instanceof Error ? err.message : String(err),
|
||||
bodySnippet: text?.slice(0, 200)
|
||||
});
|
||||
throw new ExternalServiceError('IdNot', `Invalid JSON response (${response.status} ${response.statusText}): ${text?.slice(0, 120) || 'no body'}`);
|
||||
}
|
||||
}
|
||||
static async exchangeCodeForTokens(code: string) {
|
||||
const {
|
||||
IDNOT_CLIENT_ID,
|
||||
@ -67,12 +99,10 @@ export class IdNotService {
|
||||
const url = `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/personnes/${idNot}/rattachements?${searchParams}`;
|
||||
|
||||
const response = await fetch(url, { method: 'GET' });
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch rattachements: ${response.status} ${response.statusText}`);
|
||||
throw new ExternalServiceError('IdNot', `Failed to fetch rattachements: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return await IdNotService.parseJsonOrThrow(response as any, 'getUserRattachements');
|
||||
}
|
||||
|
||||
static async getOfficeRattachements(idNot: string) {
|
||||
@ -89,13 +119,11 @@ export class IdNotService {
|
||||
|
||||
const url = `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/entites/${idNot}/personnes?` + searchParams;
|
||||
|
||||
const json = await (
|
||||
await fetch(url, {
|
||||
method: 'GET'
|
||||
})
|
||||
).json();
|
||||
|
||||
return json;
|
||||
const response = await fetch(url, { method: 'GET' });
|
||||
if (!response.ok) {
|
||||
throw new ExternalServiceError('IdNot', `Failed to fetch office rattachements: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
return await IdNotService.parseJsonOrThrow(response as any, 'getOfficeRattachements');
|
||||
}
|
||||
|
||||
static async getUserData(profileIdn: string) {
|
||||
@ -109,13 +137,11 @@ export class IdNotService {
|
||||
key: IDNOT_API_KEY
|
||||
});
|
||||
|
||||
const userData = await (
|
||||
await fetch(`${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams, {
|
||||
method: 'GET'
|
||||
})
|
||||
).json();
|
||||
|
||||
return userData;
|
||||
const response = await fetch(`${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams, { method: 'GET' });
|
||||
if (!response.ok) {
|
||||
throw new ExternalServiceError('IdNot', `Failed to fetch user data: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
return await IdNotService.parseJsonOrThrow(response as any, 'getUserData');
|
||||
}
|
||||
|
||||
static async getOfficeLocationData(locationsUrl: string) {
|
||||
@ -129,13 +155,11 @@ export class IdNotService {
|
||||
key: IDNOT_API_KEY
|
||||
});
|
||||
|
||||
const officeLocationData = await (
|
||||
await fetch(`${IDNOT_API_BASE_URL}${locationsUrl}?` + searchParams, {
|
||||
method: 'GET'
|
||||
})
|
||||
).json();
|
||||
|
||||
return officeLocationData;
|
||||
const response = await fetch(`${IDNOT_API_BASE_URL}${locationsUrl}?` + searchParams, { method: 'GET' });
|
||||
if (!response.ok) {
|
||||
throw new ExternalServiceError('IdNot', `Failed to fetch office location data: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
return await IdNotService.parseJsonOrThrow(response as any, 'getOfficeLocationData');
|
||||
}
|
||||
|
||||
static getOfficeStatus(statusName: string): EOfficeStatus {
|
||||
|
Loading…
x
Reference in New Issue
Block a user