From 1742a2df0ae826d03643e56858875045e7b4b62c Mon Sep 17 00:00:00 2001 From: Long Zheng Date: Thu, 23 Jan 2025 20:25:45 +1100 Subject: [PATCH] Fix crashing when CSIP server errors for DefaultDerControl and DerControlList Related to #75 --- src/sep2/helpers/derProgramList.ts | 83 +++++++++++++++++++----------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/src/sep2/helpers/derProgramList.ts b/src/sep2/helpers/derProgramList.ts index b216f84..e1a471c 100644 --- a/src/sep2/helpers/derProgramList.ts +++ b/src/sep2/helpers/derProgramList.ts @@ -15,6 +15,8 @@ import { import { parseDerControlListXml } from '../models/derControlList.js'; import { derControlSchema } from '../models/derControl.js'; import { z } from 'zod'; +import { type Logger } from 'pino'; +import { pinoLogger } from '../../helpers/logger.js'; export const derProgramListDataSchema = z.array( z.object({ @@ -33,11 +35,15 @@ export class DerProgramListHelper extends EventEmitter<{ private client: SEP2Client; private derProgramListPollableResource: DerProgramListPollableResource | null = null; + private logger: Logger; constructor({ client }: { client: SEP2Client }) { super(); this.client = client; + this.logger = pinoLogger.child({ + module: 'DerProgramListHelper', + }); } updateHref({ href }: { href: string }) { @@ -54,41 +60,58 @@ export class DerProgramListHelper extends EventEmitter<{ defaultPollPushRates.functionSetAssignmentsListPoll, }).on('data', (data) => { void (async () => { - const result: DerProgramListData = []; + // this function calls SEP2Client requests directly (without polling) + // it has been observed some CSIP utility servers will randomly error consistently (and exceed the retry limit) + // in this scenario the application will crash since we await DefaultDerControl and DerControlList data + // however we can safely ignore these errors since the data will be requested again on the next poll of DerProgramList + try { + const result: DerProgramListData = []; + + for (const program of data.derPrograms) { + const defaultDerControl = + program.defaultDerControlLink + ? parseDefaultDERControlXml( + await this.client.get( + program.defaultDerControlLink + .href, + ), + ) + : undefined; - for (const program of data.derPrograms) { - const defaultDerControl = - program.defaultDerControlLink - ? parseDefaultDERControlXml( - await this.client.get( - program.defaultDerControlLink + const derControlList = + program.derControlListLink + ? await getListAll({ + client: this.client, + url: program.derControlListLink .href, - ), - ) - : undefined; + parseXml: parseDerControlListXml, + addItems: ( + allResults, + result, + ) => { + allResults.derControls.push( + ...result.derControls, + ); + }, + getItems: (result) => + result.derControls, + }) + : undefined; - const derControlList = program.derControlListLink - ? await getListAll({ - client: this.client, - url: program.derControlListLink.href, - parseXml: parseDerControlListXml, - addItems: (allResults, result) => { - allResults.derControls.push( - ...result.derControls, - ); - }, - getItems: (result) => result.derControls, - }) - : undefined; + result.push({ + program, + defaultDerControl, + derControls: derControlList?.derControls, + }); + } - result.push({ - program, - defaultDerControl, - derControls: derControlList?.derControls, - }); + this.emit('data', result); + } catch (error) { + this.logger.error( + error, + 'Error processing DerProgramList data', + ); } - - this.emit('data', result); })(); }); }