jspurefix 5.11.0 → 5.11.1

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.
@@ -0,0 +1,2 @@
1
+ export declare function describeConnectError(e: unknown): string;
2
+ export declare function withConnectReason(e: Error): Error;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeConnectError = describeConnectError;
4
+ exports.withConnectReason = withConnectReason;
5
+ function describeConnectError(e) {
6
+ if (e == null)
7
+ return 'unknown error';
8
+ const described = detail(e);
9
+ return described.length > 0 ? described : String(e);
10
+ }
11
+ function detail(e) {
12
+ if (e == null)
13
+ return '';
14
+ const err = e;
15
+ if (Array.isArray(err.errors) && err.errors.length > 0) {
16
+ const unique = Array.from(new Set(err.errors.map(detail).filter(m => m.length > 0)));
17
+ if (unique.length > 0)
18
+ return unique.join('; ');
19
+ }
20
+ if (err.message)
21
+ return err.message;
22
+ if (err.code)
23
+ return err.code;
24
+ return '';
25
+ }
26
+ function withConnectReason(e) {
27
+ if (!e.message) {
28
+ e.message = describeConnectError(e);
29
+ }
30
+ return e;
31
+ }
32
+ //# sourceMappingURL=connect-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-error.js","sourceRoot":"","sources":["../../../src/transport/tcp/connect-error.ts"],"names":[],"mappings":";;AAaA,oDAIC;AAiCD,8CAKC;AA1CD,SAAgB,oBAAoB,CAAE,CAAU;IAC9C,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,eAAe,CAAA;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC;AASD,SAAS,MAAM,CAAE,CAAU;IACzB,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAExB,MAAM,GAAG,GAAG,CAA4D,CAAA;IAExE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAGvD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACpF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjD,CAAC;IAED,IAAI,GAAG,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC,OAAO,CAAA;IACnC,IAAI,GAAG,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC,IAAI,CAAA;IAC7B,OAAO,EAAE,CAAA;AACX,CAAC;AASD,SAAgB,iBAAiB,CAAE,CAAQ;IACzC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACf,CAAC,CAAC,OAAO,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAA;IACrC,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * A readable reason for a failed connection.\n *\n * Node raises an AggregateError when the host resolved to more than one address and\n * every attempt failed. That is not an edge case: 'localhost' is both ::1 and\n * 127.0.0.1 on any modern machine, so it is what an ordinary refused connection looks\n * like. Its own message is empty and the detail sits in errors[], so reporting\n * e.message alone said nothing at all about the commonest failure there is - an\n * application catching a rejected connect saw an Error with no message.\n *\n * Falls back to the code (ECONNREFUSED, ENOTFOUND, ETIMEDOUT) when there is no\n * message anywhere, which is still enough to act on.\n */\nexport function describeConnectError (e: unknown): string {\n if (e == null) return 'unknown error'\n const described = detail(e)\n return described.length > 0 ? described : String(e)\n}\n\n/**\n * The reason, or '' when this error carries none.\n *\n * Kept separate from the public function so a nested error with nothing to say\n * contributes nothing, rather than a stringified 'Error' that would then look like a\n * reason and stop the aggregate falling back to its own code.\n */\nfunction detail (e: unknown): string {\n if (e == null) return ''\n\n const err = e as { message?: string, code?: string, errors?: unknown[] }\n\n if (Array.isArray(err.errors) && err.errors.length > 0) {\n // every address usually fails the same way - say it once rather than repeating\n // 'connect ECONNREFUSED' for each family\n const unique = Array.from(new Set(err.errors.map(detail).filter(m => m.length > 0)))\n if (unique.length > 0) return unique.join('; ')\n }\n\n if (err.message) return err.message\n if (err.code) return err.code\n return ''\n}\n\n/**\n * Give an error a message when it has none, keeping the object itself.\n *\n * Deliberately not a wrapper: `code` and `errors` are what a caller switches on, and\n * building a fresh Error to hold the text would throw both away. Returns the same\n * error so it can be used inline.\n */\nexport function withConnectReason (e: Error): Error {\n if (!e.message) {\n e.message = describeConnectError(e)\n }\n return e\n}\n"]}
@@ -28,6 +28,7 @@ const session_state_1 = require("../session/session-state");
28
28
  const tsyringe_1 = require("tsyringe");
29
29
  const di_tokens_1 = require("../../runtime/di-tokens");
30
30
  const fix_entity_1 = require("../fix-entity");
31
+ const connect_error_1 = require("./connect-error");
31
32
  let RecoveringTcpInitiator = RecoveringTcpInitiator_1 = class RecoveringTcpInitiator extends fix_entity_1.FixEntity {
32
33
  constructor(jsFixConfig) {
33
34
  var _a, _b, _c, _d, _e, _f, _g;
@@ -140,7 +141,7 @@ let RecoveringTcpInitiator = RecoveringTcpInitiator_1 = class RecoveringTcpIniti
140
141
  this.connect(this.connectTimeoutSecs).then(t => {
141
142
  this.logger.info(`new transport ${t.id}`);
142
143
  }).catch((e) => {
143
- this.logger.info(`failed to re-connect ${e.message} - backoff for ${this.backoffFailConnectSecs}`);
144
+ this.logger.info(`failed to re-connect: ${(0, connect_error_1.describeConnectError)(e)} - backoff for ${this.backoffFailConnectSecs}`);
144
145
  this.th = setTimeout(() => {
145
146
  this.logger.info('returning to recover()');
146
147
  setImmediate(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"recovering-tcp-initiator.js","sourceRoot":"","sources":["../../../src/transport/tcp/recovering-tcp-initiator.ts"],"names":[],"mappings":"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","sourcesContent":["import { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport { TcpInitiator } from './tcp-initiator'\nimport { MsgTransport } from '../factory'\nimport Timeout = NodeJS.Timeout\nimport { SessionState } from '../session/session-state'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ITcpTransportDescription } from './tcp-transport-description'\nimport { IMsgApplication } from '../msg-application'\nimport { FixEntity } from '../fix-entity'\n\n/*\n create one application session instance - and recover a lost transport. Hence, the application\n will automatically re-connected and the \"message recovery\" policy enacted i.e. replay from\n last known sequence number or sequence reset.\n */\n\n@injectable()\nexport class RecoveringTcpInitiator extends FixEntity {\n public tcp: ITcpTransportDescription | null\n public session: FixSession\n private readonly logger: IJsFixLogger\n private readonly application: IMsgApplication | null\n private initiator: TcpInitiator\n private transport: MsgTransport\n private th: Timeout | null = null\n private stopRequested: boolean = false\n public static readonly DefaultRecoveryAttemptSecs = 5\n public static readonly DefaultBackoffFailConnectSecs = 30\n public static readonly DefaultConnectTimeoutSecs = 60\n\n public recoveryAttemptSecs: number = RecoveringTcpInitiator.DefaultRecoveryAttemptSecs\n public backoffFailConnectSecs: number = RecoveringTcpInitiator.DefaultBackoffFailConnectSecs\n public connectTimeoutSecs: number = RecoveringTcpInitiator.DefaultConnectTimeoutSecs\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly jsFixConfig: IJsFixConfig) {\n super(jsFixConfig)\n this.application = this.jsFixConfig.description.application ?? null\n const name = this.application?.name ?? 'na'\n this.logger = jsFixConfig.logFactory.logger(`${name}:RecoveringTcpInitiator`)\n if (!this.application) {\n throw new Error('no application in session description.')\n }\n this.tcp = this.application.tcp ?? null\n if (!this.tcp) {\n throw new Error('no tcp in session description need tcp { host: hostname, port: port }')\n }\n // the retry policy used to live only in these fields, which nothing set - an\n // application could not change how hard or how long the engine tried to get its\n // transport back without subclassing the launcher. See issue #72.\n this.recoveryAttemptSecs = this.application.recoveryAttemptSeconds ?? this.recoveryAttemptSecs\n this.backoffFailConnectSecs = this.application.backoffFailConnectSeconds ?? this.backoffFailConnectSecs\n this.connectTimeoutSecs = this.application.connectTimeoutSeconds ?? this.connectTimeoutSecs\n this.logger.info(`recovery policy: connectTimeout=${this.connectTimeoutSecs}s, ` +\n `recoveryAttempt=${this.recoveryAttemptSecs}s, backoffFailConnect=${this.backoffFailConnectSecs}s`)\n this.createSession(jsFixConfig)\n }\n\n private createSession (jsFixConfig: IJsFixConfig): void {\n this.logger.info(`creating an application session with DI token ${DITokens.FixSession}.`)\n this.session = jsFixConfig.sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.session.on('done', () => {\n this.logger.info('session has permanently ended')\n this.emit('end', this)\n })\n this.session.on('end', () => {\n this.logger.info('session has permanently ended')\n this.emit('end', this)\n })\n // A lost transport is this initiator's normal course of events, and recovery is\n // driven by session.run() rejecting rather than by this event. But whilst waiting\n // between attempts there is no run in flight to carry a listener, so a stop landing\n // then would emit 'error' to nobody - which node treats as fatal.\n this.session.on('error', (e: Error) => {\n this.logger.info(`session error: ${e.message}`)\n })\n this.session.setState(SessionState.DisconnectedNoConnectionToday)\n }\n\n public getState (): SessionState {\n return this.session.getState()\n }\n\n public lastSentSeqNum (): number {\n return this.session.lastSentSeqNum()\n }\n\n private resetSeq (): boolean {\n return this.jsFixConfig.description.ResetSeqNumFlag\n }\n\n private newTransport (transport: MsgTransport): void {\n this.transport = transport\n this.emit('transport', transport)\n this.logger.info(`initiator connects id ${(transport.id)}`)\n const session = this.session\n if (this.resetSeq()) {\n this.logger.info('reset sequence numbers')\n session.reset()\n }\n session.setState(SessionState.NetworkConnectionEstablished)\n session.run(transport).then((id: number) => {\n if (!transport || id === transport.id) {\n this.emit('end', this)\n } else {\n this.logger.info(`old transport ${id} ends waiting on ${(transport.id)}`)\n }\n }).catch(e => {\n this.logger.info(`transport id ${(transport.id)} failed - session state ${session.getState()}`)\n this.logger.warning(e.message)\n this.recover()\n })\n this.logger.info(`running session with transport ${transport.id} state = ${session.getState()}`)\n }\n\n private clearTimer (): void {\n if (this.th) {\n clearTimeout(this.th)\n this.th = null\n }\n }\n\n // at least one connection was established so retry to establish - either\n // succeed in which case can restart session or fails in which case wait and\n // restart an attempt to connect\n\n /**\n * Give up recovering and end the session for good.\n *\n * Without this a resilient initiator could not be shut down: losing the transport\n * schedules another attempt, and nothing cancelled that timer, so the process stayed\n * alive retrying a counterparty the application had finished with. Safe to call\n * twice, and safe whilst waiting between attempts with no transport at all.\n */\n public stop (): void {\n if (this.stopRequested) return\n this.stopRequested = true\n this.logger.info('stop requested - cancelling recovery')\n this.clearTimer()\n if (this.session.getState() !== SessionState.Stopped) {\n this.session.requestStop('initiator stopped')\n }\n this.emit('end', this)\n }\n\n private recover (): void {\n if (this.stopRequested) {\n this.logger.info('transport lost after a stop was requested - not recovering')\n this.emit('end', this)\n return\n }\n this.session.setState(SessionState.DetectBrokenNetworkConnection)\n this.logger.info(`recover session transport - attempt in ${this.recoveryAttemptSecs} secs`)\n if (!this.resetSeq()) {\n const lastSentSeqNum = this.lastSentSeqNum()\n if (lastSentSeqNum > 0) {\n this.logger.info(`recover session set LastSentSeqNum ${lastSentSeqNum} for new transport`)\n this.config.description.LastSentSeqNum = lastSentSeqNum\n }\n }\n this.th = setTimeout(() => {\n this.connect(this.connectTimeoutSecs).then(t => {\n this.logger.info(`new transport ${t.id}`)\n }).catch((e) => {\n this.logger.info(`failed to re-connect ${e.message} - backoff for ${this.backoffFailConnectSecs}`)\n this.th = setTimeout(() => {\n this.logger.info('returning to recover()')\n setImmediate(() => {\n this.recover()\n })\n }, this.backoffFailConnectSecs * 1000)\n })\n }, this.recoveryAttemptSecs * 1000)\n }\n\n public async start (): Promise<any> {\n return await this.run()\n }\n\n // for first connection - reject if no initial connection established within timeout\n // once connection established, will not resolve until session is ended - i.e. lost\n // connections are re-established using the same session instance. So this promise\n // is the lifetime of the application, not a signal that the session is up: for that,\n // use onReady on the session. See issue #72.\n\n public async run (initialTimeout: number = this.connectTimeoutSecs): Promise<any> {\n return await new Promise<any>((resolve, reject) => {\n // 'end' can arrive more than once - a stop both ends the session and calls off\n // recovery, and each path announces itself - so settle only on the first. The\n // listener goes on before connecting, not after: a stop landing whilst the first\n // connection is still being attempted has to be able to end this too, and until\n // now there was nothing listening that early to hear it.\n let ended = false\n const finish = (): void => {\n if (ended) return\n ended = true\n this.clearTimer()\n this.initiator?.end()\n this.logger.info(`run: transport ${this.transport?.id ?? 'none'} ends - resolving`)\n resolve(null)\n }\n this.on('end', finish)\n\n this.connect(initialTimeout).catch(e => {\n if (this.stopRequested) {\n this.logger.info('run: first connection abandoned on stop - resolving')\n finish()\n return\n }\n this.logger.info(`run: failed to connect to first transport ${initialTimeout} - rejecting`)\n reject(e)\n })\n })\n }\n\n // return a promise for new transport - or reject if no connection within timeout\n\n private async connect (timeout: number): Promise<MsgTransport> {\n return await new Promise<MsgTransport>((resolve, reject) => {\n this.logger.info(`connect: start initiator timeout ${timeout}`)\n this.session.setState(SessionState.InitiateConnection)\n this.initiator = new TcpInitiator(this.jsFixConfig)\n this.initiator.connect(timeout).then((transport: MsgTransport) => {\n this.logger.info(`connect: receive new transport ${transport.id}`)\n this.newTransport(transport)\n resolve(transport)\n }).catch(e => {\n this.logger.info(`connect: failed to connect within ${timeout} - rejecting`)\n this.session.setState(SessionState.DetectBrokenNetworkConnection)\n reject(e)\n })\n })\n }\n}\n"]}
1
+ {"version":3,"file":"recovering-tcp-initiator.js","sourceRoot":"","sources":["../../../src/transport/tcp/recovering-tcp-initiator.ts"],"names":[],"mappings":"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","sourcesContent":["import { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport { TcpInitiator } from './tcp-initiator'\nimport { MsgTransport } from '../factory'\nimport Timeout = NodeJS.Timeout\nimport { SessionState } from '../session/session-state'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ITcpTransportDescription } from './tcp-transport-description'\nimport { IMsgApplication } from '../msg-application'\nimport { FixEntity } from '../fix-entity'\nimport { describeConnectError } from './connect-error'\n\n/*\n create one application session instance - and recover a lost transport. Hence, the application\n will automatically re-connected and the \"message recovery\" policy enacted i.e. replay from\n last known sequence number or sequence reset.\n */\n\n@injectable()\nexport class RecoveringTcpInitiator extends FixEntity {\n public tcp: ITcpTransportDescription | null\n public session: FixSession\n private readonly logger: IJsFixLogger\n private readonly application: IMsgApplication | null\n private initiator: TcpInitiator\n private transport: MsgTransport\n private th: Timeout | null = null\n private stopRequested: boolean = false\n public static readonly DefaultRecoveryAttemptSecs = 5\n public static readonly DefaultBackoffFailConnectSecs = 30\n public static readonly DefaultConnectTimeoutSecs = 60\n\n public recoveryAttemptSecs: number = RecoveringTcpInitiator.DefaultRecoveryAttemptSecs\n public backoffFailConnectSecs: number = RecoveringTcpInitiator.DefaultBackoffFailConnectSecs\n public connectTimeoutSecs: number = RecoveringTcpInitiator.DefaultConnectTimeoutSecs\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly jsFixConfig: IJsFixConfig) {\n super(jsFixConfig)\n this.application = this.jsFixConfig.description.application ?? null\n const name = this.application?.name ?? 'na'\n this.logger = jsFixConfig.logFactory.logger(`${name}:RecoveringTcpInitiator`)\n if (!this.application) {\n throw new Error('no application in session description.')\n }\n this.tcp = this.application.tcp ?? null\n if (!this.tcp) {\n throw new Error('no tcp in session description need tcp { host: hostname, port: port }')\n }\n // the retry policy used to live only in these fields, which nothing set - an\n // application could not change how hard or how long the engine tried to get its\n // transport back without subclassing the launcher. See issue #72.\n this.recoveryAttemptSecs = this.application.recoveryAttemptSeconds ?? this.recoveryAttemptSecs\n this.backoffFailConnectSecs = this.application.backoffFailConnectSeconds ?? this.backoffFailConnectSecs\n this.connectTimeoutSecs = this.application.connectTimeoutSeconds ?? this.connectTimeoutSecs\n this.logger.info(`recovery policy: connectTimeout=${this.connectTimeoutSecs}s, ` +\n `recoveryAttempt=${this.recoveryAttemptSecs}s, backoffFailConnect=${this.backoffFailConnectSecs}s`)\n this.createSession(jsFixConfig)\n }\n\n private createSession (jsFixConfig: IJsFixConfig): void {\n this.logger.info(`creating an application session with DI token ${DITokens.FixSession}.`)\n this.session = jsFixConfig.sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.session.on('done', () => {\n this.logger.info('session has permanently ended')\n this.emit('end', this)\n })\n this.session.on('end', () => {\n this.logger.info('session has permanently ended')\n this.emit('end', this)\n })\n // A lost transport is this initiator's normal course of events, and recovery is\n // driven by session.run() rejecting rather than by this event. But whilst waiting\n // between attempts there is no run in flight to carry a listener, so a stop landing\n // then would emit 'error' to nobody - which node treats as fatal.\n this.session.on('error', (e: Error) => {\n this.logger.info(`session error: ${e.message}`)\n })\n this.session.setState(SessionState.DisconnectedNoConnectionToday)\n }\n\n public getState (): SessionState {\n return this.session.getState()\n }\n\n public lastSentSeqNum (): number {\n return this.session.lastSentSeqNum()\n }\n\n private resetSeq (): boolean {\n return this.jsFixConfig.description.ResetSeqNumFlag\n }\n\n private newTransport (transport: MsgTransport): void {\n this.transport = transport\n this.emit('transport', transport)\n this.logger.info(`initiator connects id ${(transport.id)}`)\n const session = this.session\n if (this.resetSeq()) {\n this.logger.info('reset sequence numbers')\n session.reset()\n }\n session.setState(SessionState.NetworkConnectionEstablished)\n session.run(transport).then((id: number) => {\n if (!transport || id === transport.id) {\n this.emit('end', this)\n } else {\n this.logger.info(`old transport ${id} ends waiting on ${(transport.id)}`)\n }\n }).catch(e => {\n this.logger.info(`transport id ${(transport.id)} failed - session state ${session.getState()}`)\n this.logger.warning(e.message)\n this.recover()\n })\n this.logger.info(`running session with transport ${transport.id} state = ${session.getState()}`)\n }\n\n private clearTimer (): void {\n if (this.th) {\n clearTimeout(this.th)\n this.th = null\n }\n }\n\n // at least one connection was established so retry to establish - either\n // succeed in which case can restart session or fails in which case wait and\n // restart an attempt to connect\n\n /**\n * Give up recovering and end the session for good.\n *\n * Without this a resilient initiator could not be shut down: losing the transport\n * schedules another attempt, and nothing cancelled that timer, so the process stayed\n * alive retrying a counterparty the application had finished with. Safe to call\n * twice, and safe whilst waiting between attempts with no transport at all.\n */\n public stop (): void {\n if (this.stopRequested) return\n this.stopRequested = true\n this.logger.info('stop requested - cancelling recovery')\n this.clearTimer()\n if (this.session.getState() !== SessionState.Stopped) {\n this.session.requestStop('initiator stopped')\n }\n this.emit('end', this)\n }\n\n private recover (): void {\n if (this.stopRequested) {\n this.logger.info('transport lost after a stop was requested - not recovering')\n this.emit('end', this)\n return\n }\n this.session.setState(SessionState.DetectBrokenNetworkConnection)\n this.logger.info(`recover session transport - attempt in ${this.recoveryAttemptSecs} secs`)\n if (!this.resetSeq()) {\n const lastSentSeqNum = this.lastSentSeqNum()\n if (lastSentSeqNum > 0) {\n this.logger.info(`recover session set LastSentSeqNum ${lastSentSeqNum} for new transport`)\n this.config.description.LastSentSeqNum = lastSentSeqNum\n }\n }\n this.th = setTimeout(() => {\n this.connect(this.connectTimeoutSecs).then(t => {\n this.logger.info(`new transport ${t.id}`)\n }).catch((e) => {\n this.logger.info(`failed to re-connect: ${describeConnectError(e)} - backoff for ${this.backoffFailConnectSecs}`)\n this.th = setTimeout(() => {\n this.logger.info('returning to recover()')\n setImmediate(() => {\n this.recover()\n })\n }, this.backoffFailConnectSecs * 1000)\n })\n }, this.recoveryAttemptSecs * 1000)\n }\n\n public async start (): Promise<any> {\n return await this.run()\n }\n\n // for first connection - reject if no initial connection established within timeout\n // once connection established, will not resolve until session is ended - i.e. lost\n // connections are re-established using the same session instance. So this promise\n // is the lifetime of the application, not a signal that the session is up: for that,\n // use onReady on the session. See issue #72.\n\n public async run (initialTimeout: number = this.connectTimeoutSecs): Promise<any> {\n return await new Promise<any>((resolve, reject) => {\n // 'end' can arrive more than once - a stop both ends the session and calls off\n // recovery, and each path announces itself - so settle only on the first. The\n // listener goes on before connecting, not after: a stop landing whilst the first\n // connection is still being attempted has to be able to end this too, and until\n // now there was nothing listening that early to hear it.\n let ended = false\n const finish = (): void => {\n if (ended) return\n ended = true\n this.clearTimer()\n this.initiator?.end()\n this.logger.info(`run: transport ${this.transport?.id ?? 'none'} ends - resolving`)\n resolve(null)\n }\n this.on('end', finish)\n\n this.connect(initialTimeout).catch(e => {\n if (this.stopRequested) {\n this.logger.info('run: first connection abandoned on stop - resolving')\n finish()\n return\n }\n this.logger.info(`run: failed to connect to first transport ${initialTimeout} - rejecting`)\n reject(e)\n })\n })\n }\n\n // return a promise for new transport - or reject if no connection within timeout\n\n private async connect (timeout: number): Promise<MsgTransport> {\n return await new Promise<MsgTransport>((resolve, reject) => {\n this.logger.info(`connect: start initiator timeout ${timeout}`)\n this.session.setState(SessionState.InitiateConnection)\n this.initiator = new TcpInitiator(this.jsFixConfig)\n this.initiator.connect(timeout).then((transport: MsgTransport) => {\n this.logger.info(`connect: receive new transport ${transport.id}`)\n this.newTransport(transport)\n resolve(transport)\n }).catch(e => {\n this.logger.info(`connect: failed to connect within ${timeout} - rejecting`)\n this.session.setState(SessionState.DetectBrokenNetworkConnection)\n reject(e)\n })\n })\n }\n}\n"]}
@@ -29,6 +29,7 @@ const tls_1 = require("tls");
29
29
  const net_1 = require("net");
30
30
  const tls_options_factory_1 = require("./tls-options-factory");
31
31
  const tls_diagnostics_1 = require("./tls-diagnostics");
32
+ const connect_error_1 = require("./connect-error");
32
33
  const tsyringe_1 = require("tsyringe");
33
34
  const di_tokens_1 = require("../../runtime/di-tokens");
34
35
  var InitiatorState;
@@ -82,7 +83,7 @@ let TcpInitiator = class TcpInitiator extends fix_initiator_1.FixInitiator {
82
83
  this.tryConnect()
83
84
  .then((t) => { resolve(t); })
84
85
  .catch((first) => {
85
- this.logger.info(`first connect attempt failed: ${first.message}`);
86
+ this.logger.info(`first connect attempt failed: ${(0, connect_error_1.describeConnectError)(first)}`);
86
87
  this.repeatConnect(timeoutSeconds, first)
87
88
  .then((t) => { resolve(t); })
88
89
  .catch((e) => { reject(e); });
@@ -223,13 +224,13 @@ let TcpInitiator = class TcpInitiator extends fix_initiator_1.FixInitiator {
223
224
  resolve(t);
224
225
  }).catch((e) => {
225
226
  lastError = e;
226
- this.logger.info(`${name}: retries ${retries} ${e.message}`);
227
+ this.logger.info(`${name}: retries ${retries} ${(0, connect_error_1.describeConnectError)(e)}`);
227
228
  });
228
229
  }, reconnectSeconds * 1000);
229
230
  this.timeoutTh = setTimeout(() => {
230
231
  this.clearTimer();
231
232
  this.state = InitiatorState.Stopped;
232
- const e = lastError !== null && lastError !== void 0 ? lastError : new Error(`${name}: timeout of ${timeoutSeconds} whilst connecting`);
233
+ const e = (0, connect_error_1.withConnectReason)(lastError !== null && lastError !== void 0 ? lastError : new Error(`${name}: timeout of ${timeoutSeconds} whilst connecting`));
233
234
  this.logger.warning(`${name}: giving up after ${timeoutSeconds}s and ${retries} retries, last error: ${e.message}`);
234
235
  reject(e);
235
236
  }, timeoutSeconds * 1000);
@@ -1 +1 @@
1
- {"version":3,"file":"tcp-initiator.js","sourceRoot":"","sources":["../../../src/transport/tcp/tcp-initiator.ts"],"names":[],"mappings":"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","sourcesContent":["import { FixInitiator } from '../fix-initiator'\nimport { MsgTransport } from '../factory'\n\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { TcpDuplex, FixDuplex } from '../duplex'\n\nimport * as util from 'util'\nimport { connect as tlsConnect, ConnectionOptions, TLSSocket } from 'tls'\nimport { createConnection } from 'net'\nimport Timeout = NodeJS.Timeout\nimport { TlsOptionsFactory } from './tls-options-factory'\nimport { describeConnectionOptions, describeNegotiated, describePeerCertificate } from './tls-diagnostics'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ITcpTransportDescription } from './tcp-transport-description'\n\nexport enum InitiatorState {\n Idle = 1,\n Connecting = 2,\n Connected = 3,\n Stopped = 4\n}\n\n@injectable()\nexport class TcpInitiator extends FixInitiator {\n public tcp: ITcpTransportDescription | null\n public state: InitiatorState = InitiatorState.Idle\n private readonly logger: IJsFixLogger\n private duplex: FixDuplex\n private th: Timeout | null = null\n private timeoutTh: Timeout | null = null\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly jsFixConfig: IJsFixConfig) {\n super(jsFixConfig.description.application ?? null)\n const name = this.application?.name ?? 'initiator'\n this.logger = jsFixConfig.logFactory.logger(`${name}:TcpInitiator`)\n if (!this.application) {\n throw new Error('no application in session description.')\n }\n this.tcp = this.application.tcp ?? null\n if (!this.tcp) {\n throw new Error('no tcp in session description need tcp { host: hostname, port: port }')\n }\n }\n\n public end (): void {\n this.clearTimer()\n switch (this.state) {\n case InitiatorState.Connected: {\n this.logger.info('end')\n this.duplex.end()\n this.state = InitiatorState.Stopped\n break\n }\n\n default: {\n this.logger.info(`end :state ${this.state}`)\n this.state = InitiatorState.Stopped\n break\n }\n }\n }\n\n public async connect (timeoutSeconds: number): Promise<MsgTransport> {\n return await new Promise<MsgTransport>(async (resolve, reject) => {\n switch (this.state) {\n case InitiatorState.Idle: {\n this.state = InitiatorState.Connecting\n this.logger.info(`connecting with timeout ${timeoutSeconds}`)\n this.tryConnect()\n .then((t: MsgTransport) => { resolve(t) })\n .catch((first: Error) => {\n // carry the first failure into repeatConnect. it used to be discarded, so a\n // connect() whose timeout expires before the first retry interval fires - the\n // default case, timeout and reconnectSeconds are both 5 - reported a generic\n // \"timeout whilst connecting\" and threw away the reason. see #94.\n this.logger.info(`first connect attempt failed: ${first.message}`)\n this.repeatConnect(timeoutSeconds, first)\n .then((t: MsgTransport) => { resolve(t) })\n .catch((e: Error) => { reject(e) })\n })\n break\n }\n\n default: {\n const e: Error = new Error('connect not valid from non idle state')\n this.logger.warning(`rejecting from state ${this.state}`)\n reject(e)\n }\n }\n })\n }\n\n private async unsecureDuplex (): Promise<TcpDuplex> {\n const tcp = this.tcp\n return await new Promise<TcpDuplex>((resolve, reject) => {\n try {\n this.logger.info('unsecureDuplex try to connect to endPoint')\n const socket = tcp\n ? createConnection(tcp, () => {\n try {\n this.logger.info('net.createConnection cb, resolving')\n if (socket) {\n const tcpDuplex = new TcpDuplex(socket)\n resolve(tcpDuplex)\n } else {\n reject(new Error('no socket in tcp initiator'))\n }\n } catch (e) {\n reject(e)\n }\n })\n : null\n socket?.on('error', (err) => {\n reject(err)\n })\n } catch (e) {\n reject(e)\n }\n })\n }\n\n private async tlsDuplex (): Promise<TcpDuplex > {\n return await new Promise<TcpDuplex>((resolve, reject) => {\n let tlsSocket: TLSSocket | null = null\n const tcp = this.tcp\n const connectionOptions: ConnectionOptions | null = tcp ? TlsOptionsFactory.getTlsConnectionOptions(tcp) : null\n if (connectionOptions) {\n try {\n this.logger.info(`tls connect with ${describeConnectionOptions(connectionOptions)}`)\n tlsSocket = tlsConnect(connectionOptions, () => {\n if (!tlsSocket) return null\n this.logger.info(`client connected ${tlsSocket.authorized ? 'authorized' : 'unauthorized'}`)\n this.logger.info(`tls negotiated ${describeNegotiated(tlsSocket)}`)\n this.logger.info(`tls peer certificate ${describePeerCertificate(tlsSocket)}`)\n // https://github.com/TimelordUK/jspurefix/issues/94 - honour rejectUnauthorized:\n // false rather than always rejecting on an unauthorized cert. Node's tls.connect()\n // never throws for an unauthorized peer by itself; it's the caller's job to decide\n // what to do with tlsSocket.authorized, and rejectUnauthorized is how a caller opts\n // out of that check - so only reject here when the caller didn't opt out.\n if (!tlsSocket.authorized && connectionOptions.rejectUnauthorized !== false) {\n const error = tlsSocket.authorizationError\n this.logger.warning(`rejecting from state ${this.state} authorizationError ${error}`)\n tlsSocket.end()\n reject(error)\n } else {\n if (!tlsSocket.authorized) {\n this.logger.warning(`proceeding despite unauthorized TLS peer (rejectUnauthorized: false): ${tlsSocket.authorizationError}`)\n }\n tlsSocket.setEncoding('utf8')\n const tlsDuplex = new TcpDuplex(tlsSocket)\n if (tcp?.tls?.enableTrace) {\n this.logger.info('enabling tls session trace')\n tlsSocket.enableTrace()\n }\n this.logger.info('tlsDuplex resolving')\n resolve(tlsDuplex)\n }\n })\n tlsSocket.on('error', (err) => {\n // previously silent - the socket error is the real reason a tls session failed,\n // and without it the caller only ever sees repeatConnect's generic timeout.\n this.logger.warning(`tls socket error from state ${this.state}: ${err.message}`)\n reject(err)\n })\n } catch (e) {\n reject(e)\n }\n }\n })\n }\n\n private async tryConnect (): Promise < MsgTransport > {\n return await new Promise<MsgTransport>((resolve, reject) => {\n const tcp = this.tcp\n const connectionOptions: ConnectionOptions | null = tcp ? TlsOptionsFactory.getTlsConnectionOptions(tcp) : null\n const connector = connectionOptions ? this.tlsDuplex() : this.unsecureDuplex()\n this.logger.info(`tryConnect ${tcp?.host}:${tcp?.port}`)\n connector.then(duplex => {\n this.duplex = duplex\n resolve(new MsgTransport(0, this.jsFixConfig, duplex))\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n public clearTimer (): void {\n if (this.th) {\n clearInterval(this.th)\n this.th = null\n }\n if (this.timeoutTh) {\n clearTimeout(this.timeoutTh)\n this.timeoutTh = null\n }\n }\n\n private async repeatConnect (timeoutSeconds: number, initialError?: Error): Promise < MsgTransport > {\n return await new Promise<MsgTransport>(async (resolve, reject) => {\n const application = this.application\n const reconnectSeconds = application?.reconnectSeconds ?? 5\n let retries = 0\n let lastError: Error | undefined = initialError\n const name = application?.name ?? 'initiator'\n this.th = setInterval(() => {\n ++retries\n this.tryConnect()\n .then((t: MsgTransport) => {\n this.state = InitiatorState.Connected\n this.clearTimer()\n resolve(t)\n }).catch((e: Error) => {\n lastError = e\n this.logger.info(`${name}: retries ${retries} ${e.message}`)\n })\n }, reconnectSeconds * 1000)\n // a plain timer, not a promisified one: promisify(setTimeout) hands back no\n // handle, so this deadline could never be cancelled. Connecting successfully\n // cleared the retry interval and left this one running to its full term - up to\n // the 60s an initiator allows - holding the event loop open long after the\n // session was up, and stopping a process (or a test runner) from exiting.\n this.timeoutTh = setTimeout(() => {\n this.clearTimer()\n this.state = InitiatorState.Stopped\n const e = lastError ?? new Error(`${name}: timeout of ${timeoutSeconds} whilst connecting`)\n this.logger.warning(`${name}: giving up after ${timeoutSeconds}s and ${retries} retries, last error: ${e.message}`)\n reject(e)\n }, timeoutSeconds * 1000)\n })\n }\n}\n"]}
1
+ {"version":3,"file":"tcp-initiator.js","sourceRoot":"","sources":["../../../src/transport/tcp/tcp-initiator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,oDAA+C;AAC/C,wCAAyC;AAGzC,sCAAgD;AAEhD,6BAAyE;AACzE,6BAAsC;AAEtC,+DAAyD;AACzD,uDAA0G;AAC1G,mDAAyE;AACzE,uCAA6C;AAC7C,uDAAkD;AAGlD,IAAY,cAKX;AALD,WAAY,cAAc;IACxB,mDAAQ,CAAA;IACR,+DAAc,CAAA;IACd,6DAAa,CAAA;IACb,yDAAW,CAAA;AACb,CAAC,EALW,cAAc,8BAAd,cAAc,QAKzB;AAGM,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,4BAAY;IAQ5C,YAA4C,WAAyC;;QACnF,KAAK,CAAC,MAAA,WAAW,CAAC,WAAW,CAAC,WAAW,mCAAI,IAAI,CAAC,CAAA;QADQ,gBAAW,GAAX,WAAW,CAAc;QAN9E,UAAK,GAAmB,cAAc,CAAC,IAAI,CAAA;QAG1C,OAAE,GAAmB,IAAI,CAAA;QACzB,cAAS,GAAmB,IAAI,CAAA;QAItC,MAAM,IAAI,GAAG,MAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,IAAI,mCAAI,WAAW,CAAA;QAClD,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,eAAe,CAAC,CAAA;QACnE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,MAAA,IAAI,CAAC,WAAW,CAAC,GAAG,mCAAI,IAAI,CAAA;QACvC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;IAEM,GAAG;QACR,IAAI,CAAC,UAAU,EAAE,CAAA;QACjB,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,KAAK,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBACvB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;gBACjB,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,OAAO,CAAA;gBACnC,MAAK;YACP,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;gBAC5C,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,OAAO,CAAA;gBACnC,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAEY,OAAO,CAAE,cAAsB;;YAC1C,OAAO,MAAM,IAAI,OAAO,CAAe,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC/D,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;oBACnB,KAAK,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;wBACzB,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,UAAU,CAAA;wBACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,cAAc,EAAE,CAAC,CAAA;wBAC7D,IAAI,CAAC,UAAU,EAAE;6BACd,IAAI,CAAC,CAAC,CAAe,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC;6BACzC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;4BAKtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,IAAA,oCAAoB,EAAC,KAAK,CAAC,EAAE,CAAC,CAAA;4BAChF,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,KAAK,CAAC;iCACtC,IAAI,CAAC,CAAC,CAAe,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC;iCACzC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;wBACvC,CAAC,CAAC,CAAA;wBACJ,MAAK;oBACP,CAAC;oBAED,OAAO,CAAC,CAAC,CAAC;wBACR,MAAM,CAAC,GAAU,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;wBACnE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,wBAAwB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;wBACzD,MAAM,CAAC,CAAC,CAAC,CAAA;oBACX,CAAC;gBACH,CAAC;YACH,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;IAEa,cAAc;;YAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;YACpB,OAAO,MAAM,IAAI,OAAO,CAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtD,IAAI,CAAC;oBACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;oBAC7D,MAAM,MAAM,GAAG,GAAG;wBAChB,CAAC,CAAC,IAAA,sBAAgB,EAAC,GAAG,EAAE,GAAG,EAAE;4BAC3B,IAAI,CAAC;gCACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAA;gCACtD,IAAI,MAAM,EAAE,CAAC;oCACX,MAAM,SAAS,GAAG,IAAI,kBAAS,CAAC,MAAM,CAAC,CAAA;oCACvC,OAAO,CAAC,SAAS,CAAC,CAAA;gCACpB,CAAC;qCAAM,CAAC;oCACN,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAA;gCACjD,CAAC;4BACH,CAAC;4BAAC,OAAO,CAAC,EAAE,CAAC;gCACX,MAAM,CAAC,CAAC,CAAC,CAAA;4BACX,CAAC;wBACH,CAAC,CAAC;wBACF,CAAC,CAAC,IAAI,CAAA;oBACR,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;wBAC1B,MAAM,CAAC,GAAG,CAAC,CAAA;oBACb,CAAC,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEa,SAAS;;YACrB,OAAO,MAAM,IAAI,OAAO,CAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtD,IAAI,SAAS,GAAqB,IAAI,CAAA;gBACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;gBACpB,MAAM,iBAAiB,GAA6B,GAAG,CAAC,CAAC,CAAC,uCAAiB,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAC/G,IAAI,iBAAiB,EAAE,CAAC;oBACtB,IAAI,CAAC;wBACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,IAAA,2CAAyB,EAAC,iBAAiB,CAAC,EAAE,CAAC,CAAA;wBACpF,SAAS,GAAG,IAAA,aAAU,EAAC,iBAAiB,EAAE,GAAG,EAAE;;4BAC7C,IAAI,CAAC,SAAS;gCAAE,OAAO,IAAI,CAAA;4BAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAA;4BAC5F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,IAAA,oCAAkB,EAAC,SAAS,CAAC,EAAE,CAAC,CAAA;4BACnE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,IAAA,yCAAuB,EAAC,SAAS,CAAC,EAAE,CAAC,CAAA;4BAM9E,IAAI,CAAC,SAAS,CAAC,UAAU,IAAI,iBAAiB,CAAC,kBAAkB,KAAK,KAAK,EAAE,CAAC;gCAC5E,MAAM,KAAK,GAAG,SAAS,CAAC,kBAAkB,CAAA;gCAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,wBAAwB,IAAI,CAAC,KAAK,uBAAuB,KAAK,EAAE,CAAC,CAAA;gCACrF,SAAS,CAAC,GAAG,EAAE,CAAA;gCACf,MAAM,CAAC,KAAK,CAAC,CAAA;4BACf,CAAC;iCAAM,CAAC;gCACN,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;oCAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,yEAAyE,SAAS,CAAC,kBAAkB,EAAE,CAAC,CAAA;gCAC9H,CAAC;gCACD,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;gCAC7B,MAAM,SAAS,GAAG,IAAI,kBAAS,CAAC,SAAS,CAAC,CAAA;gCAC1C,IAAI,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,GAAG,0CAAE,WAAW,EAAE,CAAC;oCAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;oCAC9C,SAAS,CAAC,WAAW,EAAE,CAAA;gCACzB,CAAC;gCACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;gCACvC,OAAO,CAAC,SAAS,CAAC,CAAA;4BACpB,CAAC;wBACH,CAAC,CAAC,CAAA;wBACF,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;4BAG5B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,+BAA+B,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;4BAChF,MAAM,CAAC,GAAG,CAAC,CAAA;wBACb,CAAC,CAAC,CAAA;oBACJ,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,MAAM,CAAC,CAAC,CAAC,CAAA;oBACX,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEa,UAAU;;YACtB,OAAO,MAAM,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACzD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAA;gBACpB,MAAM,iBAAiB,GAA6B,GAAG,CAAC,CAAC,CAAC,uCAAiB,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;gBAC/G,MAAM,SAAS,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,CAAA;gBAC9E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,IAAI,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,EAAE,CAAC,CAAA;gBACxD,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;oBACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;oBACpB,OAAO,CAAC,IAAI,sBAAY,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;gBACxD,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;oBACX,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEM,UAAU;QACf,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACtB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAA;QAChB,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC5B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;QACvB,CAAC;IACH,CAAC;IAEa,aAAa,CAAE,cAAsB,EAAE,YAAoB;;YACvE,OAAO,MAAM,IAAI,OAAO,CAAe,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;;gBAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;gBACpC,MAAM,gBAAgB,GAAG,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,mCAAI,CAAC,CAAA;gBAC3D,IAAI,OAAO,GAAG,CAAC,CAAA;gBACf,IAAI,SAAS,GAAsB,YAAY,CAAA;gBAC/C,MAAM,IAAI,GAAG,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,mCAAI,WAAW,CAAA;gBAC7C,IAAI,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;oBACzB,EAAE,OAAO,CAAA;oBACT,IAAI,CAAC,UAAU,EAAE;yBACd,IAAI,CAAC,CAAC,CAAe,EAAE,EAAE;wBACxB,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,SAAS,CAAA;wBACrC,IAAI,CAAC,UAAU,EAAE,CAAA;wBACjB,OAAO,CAAC,CAAC,CAAC,CAAA;oBACZ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;wBACpB,SAAS,GAAG,CAAC,CAAA;wBACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,aAAa,OAAO,IAAI,IAAA,oCAAoB,EAAC,CAAC,CAAC,EAAE,CAAC,CAAA;oBAC5E,CAAC,CAAC,CAAA;gBACN,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC,CAAA;gBAM3B,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC/B,IAAI,CAAC,UAAU,EAAE,CAAA;oBACjB,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,OAAO,CAAA;oBAInC,MAAM,CAAC,GAAG,IAAA,iCAAiB,EAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,IAAI,KAAK,CAAC,GAAG,IAAI,gBAAgB,cAAc,oBAAoB,CAAC,CAAC,CAAA;oBAC9G,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,qBAAqB,cAAc,SAAS,OAAO,yBAAyB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;oBACnH,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC,CAAA;YAC3B,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;CACF,CAAA;AAlNY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,qBAAU,GAAE;IASG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GARhC,YAAY,CAkNxB","sourcesContent":["import { FixInitiator } from '../fix-initiator'\nimport { MsgTransport } from '../factory'\n\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { TcpDuplex, FixDuplex } from '../duplex'\n\nimport { connect as tlsConnect, ConnectionOptions, TLSSocket } from 'tls'\nimport { createConnection } from 'net'\nimport Timeout = NodeJS.Timeout\nimport { TlsOptionsFactory } from './tls-options-factory'\nimport { describeConnectionOptions, describeNegotiated, describePeerCertificate } from './tls-diagnostics'\nimport { describeConnectError, withConnectReason } from './connect-error'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ITcpTransportDescription } from './tcp-transport-description'\n\nexport enum InitiatorState {\n Idle = 1,\n Connecting = 2,\n Connected = 3,\n Stopped = 4\n}\n\n@injectable()\nexport class TcpInitiator extends FixInitiator {\n public tcp: ITcpTransportDescription | null\n public state: InitiatorState = InitiatorState.Idle\n private readonly logger: IJsFixLogger\n private duplex: FixDuplex\n private th: Timeout | null = null\n private timeoutTh: Timeout | null = null\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly jsFixConfig: IJsFixConfig) {\n super(jsFixConfig.description.application ?? null)\n const name = this.application?.name ?? 'initiator'\n this.logger = jsFixConfig.logFactory.logger(`${name}:TcpInitiator`)\n if (!this.application) {\n throw new Error('no application in session description.')\n }\n this.tcp = this.application.tcp ?? null\n if (!this.tcp) {\n throw new Error('no tcp in session description need tcp { host: hostname, port: port }')\n }\n }\n\n public end (): void {\n this.clearTimer()\n switch (this.state) {\n case InitiatorState.Connected: {\n this.logger.info('end')\n this.duplex.end()\n this.state = InitiatorState.Stopped\n break\n }\n\n default: {\n this.logger.info(`end :state ${this.state}`)\n this.state = InitiatorState.Stopped\n break\n }\n }\n }\n\n public async connect (timeoutSeconds: number): Promise<MsgTransport> {\n return await new Promise<MsgTransport>(async (resolve, reject) => {\n switch (this.state) {\n case InitiatorState.Idle: {\n this.state = InitiatorState.Connecting\n this.logger.info(`connecting with timeout ${timeoutSeconds}`)\n this.tryConnect()\n .then((t: MsgTransport) => { resolve(t) })\n .catch((first: Error) => {\n // carry the first failure into repeatConnect. it used to be discarded, so a\n // connect() whose timeout expires before the first retry interval fires - the\n // default case, timeout and reconnectSeconds are both 5 - reported a generic\n // \"timeout whilst connecting\" and threw away the reason. see #94.\n this.logger.info(`first connect attempt failed: ${describeConnectError(first)}`)\n this.repeatConnect(timeoutSeconds, first)\n .then((t: MsgTransport) => { resolve(t) })\n .catch((e: Error) => { reject(e) })\n })\n break\n }\n\n default: {\n const e: Error = new Error('connect not valid from non idle state')\n this.logger.warning(`rejecting from state ${this.state}`)\n reject(e)\n }\n }\n })\n }\n\n private async unsecureDuplex (): Promise<TcpDuplex> {\n const tcp = this.tcp\n return await new Promise<TcpDuplex>((resolve, reject) => {\n try {\n this.logger.info('unsecureDuplex try to connect to endPoint')\n const socket = tcp\n ? createConnection(tcp, () => {\n try {\n this.logger.info('net.createConnection cb, resolving')\n if (socket) {\n const tcpDuplex = new TcpDuplex(socket)\n resolve(tcpDuplex)\n } else {\n reject(new Error('no socket in tcp initiator'))\n }\n } catch (e) {\n reject(e)\n }\n })\n : null\n socket?.on('error', (err) => {\n reject(err)\n })\n } catch (e) {\n reject(e)\n }\n })\n }\n\n private async tlsDuplex (): Promise<TcpDuplex > {\n return await new Promise<TcpDuplex>((resolve, reject) => {\n let tlsSocket: TLSSocket | null = null\n const tcp = this.tcp\n const connectionOptions: ConnectionOptions | null = tcp ? TlsOptionsFactory.getTlsConnectionOptions(tcp) : null\n if (connectionOptions) {\n try {\n this.logger.info(`tls connect with ${describeConnectionOptions(connectionOptions)}`)\n tlsSocket = tlsConnect(connectionOptions, () => {\n if (!tlsSocket) return null\n this.logger.info(`client connected ${tlsSocket.authorized ? 'authorized' : 'unauthorized'}`)\n this.logger.info(`tls negotiated ${describeNegotiated(tlsSocket)}`)\n this.logger.info(`tls peer certificate ${describePeerCertificate(tlsSocket)}`)\n // https://github.com/TimelordUK/jspurefix/issues/94 - honour rejectUnauthorized:\n // false rather than always rejecting on an unauthorized cert. Node's tls.connect()\n // never throws for an unauthorized peer by itself; it's the caller's job to decide\n // what to do with tlsSocket.authorized, and rejectUnauthorized is how a caller opts\n // out of that check - so only reject here when the caller didn't opt out.\n if (!tlsSocket.authorized && connectionOptions.rejectUnauthorized !== false) {\n const error = tlsSocket.authorizationError\n this.logger.warning(`rejecting from state ${this.state} authorizationError ${error}`)\n tlsSocket.end()\n reject(error)\n } else {\n if (!tlsSocket.authorized) {\n this.logger.warning(`proceeding despite unauthorized TLS peer (rejectUnauthorized: false): ${tlsSocket.authorizationError}`)\n }\n tlsSocket.setEncoding('utf8')\n const tlsDuplex = new TcpDuplex(tlsSocket)\n if (tcp?.tls?.enableTrace) {\n this.logger.info('enabling tls session trace')\n tlsSocket.enableTrace()\n }\n this.logger.info('tlsDuplex resolving')\n resolve(tlsDuplex)\n }\n })\n tlsSocket.on('error', (err) => {\n // previously silent - the socket error is the real reason a tls session failed,\n // and without it the caller only ever sees repeatConnect's generic timeout.\n this.logger.warning(`tls socket error from state ${this.state}: ${err.message}`)\n reject(err)\n })\n } catch (e) {\n reject(e)\n }\n }\n })\n }\n\n private async tryConnect (): Promise < MsgTransport > {\n return await new Promise<MsgTransport>((resolve, reject) => {\n const tcp = this.tcp\n const connectionOptions: ConnectionOptions | null = tcp ? TlsOptionsFactory.getTlsConnectionOptions(tcp) : null\n const connector = connectionOptions ? this.tlsDuplex() : this.unsecureDuplex()\n this.logger.info(`tryConnect ${tcp?.host}:${tcp?.port}`)\n connector.then(duplex => {\n this.duplex = duplex\n resolve(new MsgTransport(0, this.jsFixConfig, duplex))\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n public clearTimer (): void {\n if (this.th) {\n clearInterval(this.th)\n this.th = null\n }\n if (this.timeoutTh) {\n clearTimeout(this.timeoutTh)\n this.timeoutTh = null\n }\n }\n\n private async repeatConnect (timeoutSeconds: number, initialError?: Error): Promise < MsgTransport > {\n return await new Promise<MsgTransport>(async (resolve, reject) => {\n const application = this.application\n const reconnectSeconds = application?.reconnectSeconds ?? 5\n let retries = 0\n let lastError: Error | undefined = initialError\n const name = application?.name ?? 'initiator'\n this.th = setInterval(() => {\n ++retries\n this.tryConnect()\n .then((t: MsgTransport) => {\n this.state = InitiatorState.Connected\n this.clearTimer()\n resolve(t)\n }).catch((e: Error) => {\n lastError = e\n this.logger.info(`${name}: retries ${retries} ${describeConnectError(e)}`)\n })\n }, reconnectSeconds * 1000)\n // a plain timer, not a promisified one: promisify(setTimeout) hands back no\n // handle, so this deadline could never be cancelled. Connecting successfully\n // cleared the retry interval and left this one running to its full term - up to\n // the 60s an initiator allows - holding the event loop open long after the\n // session was up, and stopping a process (or a test runner) from exiting.\n this.timeoutTh = setTimeout(() => {\n this.clearTimer()\n this.state = InitiatorState.Stopped\n // this error is what the application catches from run() - so give it a message\n // it can print. An AggregateError arrives with none at all, which meant a\n // caller handling a failed connect had nothing to report but an empty string.\n const e = withConnectReason(lastError ?? new Error(`${name}: timeout of ${timeoutSeconds} whilst connecting`))\n this.logger.warning(`${name}: giving up after ${timeoutSeconds}s and ${retries} retries, last error: ${e.message}`)\n reject(e)\n }, timeoutSeconds * 1000)\n })\n }\n}\n"]}
@@ -1,62 +1,62 @@
1
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:25.854|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=111|
2
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:25.858|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=163|
3
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:25.858|7=1|16=1|10=250|
4
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:07:25.861|122=20260815-09:07:25.861|123=Y|36=2|10=119|
5
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:27.862|58=test_server confirming logout|10=094|
6
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:30.487|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
7
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:30.488|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=158|
8
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:30.489|7=1|16=0|10=245|
9
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:07:30.490|122=20260815-09:07:30.490|123=Y|36=2|10=107|
10
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:32.491|58=test_server confirming logout|10=088|
11
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:34.865|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
12
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:34.866|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=162|
13
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:34.866|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=115|
14
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:35.277|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=111|
15
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:35.278|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
16
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:36.280|58=test_server confirming logout|10=088|
17
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:07:36.868|58=test_client initiate logout|10=118|
18
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:38.714|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
19
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:38.715|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=159|
20
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:39.716|58=test_server confirming logout|10=095|
21
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:42.080|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
22
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:42.081|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=150|
23
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260815-09:07:43.082|58=test_client initiate logout|10=101|
24
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:45.445|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
25
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:07:45.446|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=162|
26
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:46.447|58=test_server confirming logout|10=094|
27
- 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:48.805|98=0|141=Y|553=js-client|554=pwd-client|10=180|
28
- 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:48.806|45=1|372=A|373=1|58=msgType A missing required tag 108|10=014|
29
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:53.268|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=111|
30
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:53.270|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=152|
31
- 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:53.271|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=154|
32
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:07:55.271|58=test_server confirming logout|10=090|
33
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:57.858|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=120|
34
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:57.859|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=169|
35
- 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:57.861|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=084|
36
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:07:59.861|58=test_server confirming logout|10=099|
37
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:01.858|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
38
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:06.243|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=103|
39
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:06.244|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=152|
40
- 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:06.245|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=032|
41
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:08:08.269|58=test_server confirming logout|10=096|
42
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:10.697|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=061|
43
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:10.698|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
44
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:08:12.704|112=Sat, 15 Aug 2026 09:08:12 GMT|10=140|
45
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:08:14.705|112=Sat, 15 Aug 2026 09:08:14 GMT|10=146|
46
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:16.700|58=test_server confirming logout|10=084|
47
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:19.275|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=112|
48
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:19.277|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=112|
49
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:21.280|112=Sat, 15 Aug 2026 09:08:21 GMT|10=139|
50
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:08:23.285|112=Sat, 15 Aug 2026 09:08:23 GMT|10=149|
51
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260815-09:08:25.288|112=Sat, 15 Aug 2026 09:08:25 GMT|10=157|
52
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:08:27.279|58=test_server confirming logout|10=100|
53
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:29.656|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=066|
54
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:29.657|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=118|
55
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:08:31.663|112=Sat, 15 Aug 2026 09:08:31 GMT|10=146|
56
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:08:33.667|112=Sat, 15 Aug 2026 09:08:33 GMT|10=155|
57
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:34.670|112=Sat, 15 Aug 2026 09:08:34 GMT|10=150|
58
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260815-09:08:35.672|112=Sat, 15 Aug 2026 09:08:35 GMT|10=156|
59
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:08:37.659|58=test_server confirming logout|10=101|
60
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:10:23.649|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=105|
61
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:10:23.656|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
62
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:10:24.660|58=test_server confirming logout|10=081|
1
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:23.825|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
2
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:23.831|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=155|
3
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:23.832|7=1|16=1|10=243|
4
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:46:23.837|122=20260815-09:46:23.837|123=Y|36=2|10=127|
5
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:25.837|58=test_server confirming logout|10=097|
6
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:28.640|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
7
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:28.642|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
8
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:28.643|7=1|16=0|10=247|
9
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:46:28.645|122=20260815-09:46:28.645|123=Y|36=2|10=131|
10
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:30.645|58=test_server confirming logout|10=090|
11
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:33.113|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
12
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:33.114|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=150|
13
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:33.115|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
14
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:33.644|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
15
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:33.646|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
16
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:34.648|58=test_server confirming logout|10=097|
17
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:46:35.116|58=test_client initiate logout|10=106|
18
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:37.356|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=114|
19
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:37.357|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=163|
20
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:38.360|58=test_server confirming logout|10=092|
21
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:41.100|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=096|
22
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:41.101|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=145|
23
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260815-09:46:42.103|58=test_client initiate logout|10=097|
24
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:44.590|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=112|
25
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:46:44.591|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=165|
26
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:45.592|58=test_server confirming logout|10=097|
27
+ 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:48.059|98=0|141=Y|553=js-client|554=pwd-client|10=184|
28
+ 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:48.061|45=1|372=A|373=1|58=msgType A missing required tag 108|10=010|
29
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:52.637|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
30
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:52.638|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=162|
31
+ 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:52.640|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=156|
32
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:46:54.641|58=test_server confirming logout|10=093|
33
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:57.385|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=118|
34
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:57.387|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=168|
35
+ 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:57.389|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=092|
36
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:46:59.389|58=test_server confirming logout|10=107|
37
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:01.387|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
38
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:05.874|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=115|
39
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:05.876|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=165|
40
+ 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:05.877|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=045|
41
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:47:07.878|58=test_server confirming logout|10=104|
42
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:10.344|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=053|
43
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:10.346|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=153|
44
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:47:12.349|112=Sat, 15 Aug 2026 09:47:12 GMT|10=151|
45
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:47:14.351|112=Sat, 15 Aug 2026 09:47:14 GMT|10=149|
46
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:16.348|58=test_server confirming logout|10=095|
47
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:18.810|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
48
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:18.811|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=108|
49
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:20.817|112=Sat, 15 Aug 2026 09:47:20 GMT|10=149|
50
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:47:22.820|112=Sat, 15 Aug 2026 09:47:22 GMT|10=148|
51
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260815-09:47:24.822|112=Sat, 15 Aug 2026 09:47:24 GMT|10=155|
52
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:47:26.814|58=test_server confirming logout|10=097|
53
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:29.522|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=061|
54
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:29.524|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=114|
55
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:47:31.528|112=Sat, 15 Aug 2026 09:47:31 GMT|10=152|
56
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:47:33.530|112=Sat, 15 Aug 2026 09:47:33 GMT|10=150|
57
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:34.533|112=Sat, 15 Aug 2026 09:47:34 GMT|10=154|
58
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260815-09:47:35.531|112=Sat, 15 Aug 2026 09:47:35 GMT|10=156|
59
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:47:37.526|58=test_server confirming logout|10=097|
60
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:49:49.210|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
61
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:49:49.220|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=158|
62
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:49:50.224|58=test_server confirming logout|10=088|
@@ -1,75 +1,75 @@
1
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:25.854|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=111|
2
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:25.858|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=163|
3
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:25.858|7=1|16=1|10=250|
4
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:07:25.861|122=20260815-09:07:25.861|123=Y|36=2|10=119|
5
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:07:27.860|58=test_client initiate logout|10=110|
6
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:27.862|58=test_server confirming logout|10=094|
7
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:30.487|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
8
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:30.488|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=158|
9
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:30.489|7=1|16=0|10=245|
10
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:07:30.490|122=20260815-09:07:30.490|123=Y|36=2|10=107|
11
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:07:32.490|58=test_client initiate logout|10=105|
12
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:32.491|58=test_server confirming logout|10=088|
13
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:34.865|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
14
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:34.866|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=162|
15
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:34.866|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=115|
16
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:35.277|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=111|
17
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:35.278|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
18
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:36.279|58=test_client initiate logout|10=113|
19
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:36.280|58=test_server confirming logout|10=088|
20
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:38.714|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
21
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:38.715|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=159|
22
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:39.715|58=test_client initiate logout|10=111|
23
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:39.716|58=test_server confirming logout|10=095|
24
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:42.080|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
25
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:42.081|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=150|
26
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260815-09:07:43.082|58=test_client initiate logout|10=101|
27
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:45.445|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
28
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:07:45.446|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=162|
29
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:07:46.446|58=test_client initiate logout|10=110|
30
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:46.447|58=test_server confirming logout|10=094|
31
- 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:48.805|98=0|141=Y|553=js-client|554=pwd-client|10=180|
32
- 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:48.806|45=1|372=A|373=1|58=msgType A missing required tag 108|10=014|
33
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:53.268|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=111|
34
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:53.270|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=152|
1
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:23.825|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
2
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:23.831|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=155|
3
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:23.832|7=1|16=1|10=243|
4
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:46:23.837|122=20260815-09:46:23.837|123=Y|36=2|10=127|
5
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:46:25.835|58=test_client initiate logout|10=113|
6
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:25.837|58=test_server confirming logout|10=097|
7
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:28.640|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
8
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:28.642|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
9
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:28.643|7=1|16=0|10=247|
10
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260815-09:46:28.645|122=20260815-09:46:28.645|123=Y|36=2|10=131|
11
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:46:30.644|58=test_client initiate logout|10=107|
12
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:30.645|58=test_server confirming logout|10=090|
13
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:33.113|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
14
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:33.114|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=150|
15
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:33.115|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
16
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:33.644|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=110|
17
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:33.646|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
18
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:34.647|58=test_client initiate logout|10=113|
19
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:34.648|58=test_server confirming logout|10=097|
20
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:37.356|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=114|
21
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:37.357|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=163|
22
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:38.358|58=test_client initiate logout|10=116|
23
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:38.360|58=test_server confirming logout|10=092|
24
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:41.100|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=096|
25
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:41.101|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=145|
26
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260815-09:46:42.103|58=test_client initiate logout|10=097|
27
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:44.590|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=112|
28
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:46:44.591|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=165|
29
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:46:45.591|58=test_client initiate logout|10=113|
30
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:45.592|58=test_server confirming logout|10=097|
31
+ 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:48.059|98=0|141=Y|553=js-client|554=pwd-client|10=184|
32
+ 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:48.061|45=1|372=A|373=1|58=msgType A missing required tag 108|10=010|
33
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:52.637|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
34
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:52.638|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=162|
35
35
  8=FIX4.4|9=0000136|35=ZZ|49=init-comp|56=accept-comp|34=2|57=fix|52=20180902-12:25:28.980|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=177|
36
- 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:53.271|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=154|
37
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:07:55.270|58=test_client initiate logout|10=106|
38
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:07:55.271|58=test_server confirming logout|10=090|
39
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:07:57.858|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=120|
40
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:07:57.859|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=169|
36
+ 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:52.640|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=156|
37
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:46:54.640|58=test_client initiate logout|10=109|
38
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:46:54.641|58=test_server confirming logout|10=093|
39
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:46:57.385|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=118|
40
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:46:57.387|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=168|
41
41
  8=FIX4.4|9=0000123|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20180902-12:25:59.161|999=Sun, 02 Sep 2018 12:25:59 GMT|10=95|
42
- 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:07:57.861|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=084|
43
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:07:59.860|58=test_client initiate logout|10=115|
44
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:07:59.861|58=test_server confirming logout|10=099|
45
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:06.243|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=103|
46
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:06.244|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=152|
42
+ 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:46:57.389|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=092|
43
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:46:59.388|58=test_client initiate logout|10=123|
44
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:46:59.389|58=test_server confirming logout|10=107|
45
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:05.874|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=115|
46
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:05.876|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=165|
47
47
  8=FIX4.4|9=0000123|35=0|49=init-not!|56=accept-comp|34=2|57=fix|52=20180902-12:25:59.161|112=Sun, 02 Sep 2018 12:25:59 GMT|10=95|
48
- 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:06.245|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=032|
49
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:08:08.267|58=test_client initiate logout|10=111|
50
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:08:08.269|58=test_server confirming logout|10=096|
51
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:10.697|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=061|
52
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:10.698|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=160|
53
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:08:12.704|112=Sat, 15 Aug 2026 09:08:12 GMT|10=140|
54
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:08:14.705|112=Sat, 15 Aug 2026 09:08:14 GMT|10=146|
55
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260815-09:08:16.699|58=test_client initiate logout|10=120|
56
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:16.700|58=test_server confirming logout|10=084|
57
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:19.275|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=112|
58
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:19.277|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=112|
59
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:21.280|112=Sat, 15 Aug 2026 09:08:21 GMT|10=139|
60
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:08:23.285|112=Sat, 15 Aug 2026 09:08:23 GMT|10=149|
61
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260815-09:08:25.288|112=Sat, 15 Aug 2026 09:08:25 GMT|10=157|
62
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:08:27.278|58=test_client initiate logout|10=113|
63
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:08:27.279|58=test_server confirming logout|10=100|
64
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:08:29.656|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=066|
65
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:08:29.657|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=118|
66
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:08:31.663|112=Sat, 15 Aug 2026 09:08:31 GMT|10=146|
67
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:08:33.667|112=Sat, 15 Aug 2026 09:08:33 GMT|10=155|
68
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:08:34.670|112=Sat, 15 Aug 2026 09:08:34 GMT|10=150|
69
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260815-09:08:35.672|112=Sat, 15 Aug 2026 09:08:35 GMT|10=156|
70
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260815-09:08:37.658|58=test_client initiate logout|10=119|
71
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:08:37.659|58=test_server confirming logout|10=101|
72
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:10:23.649|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=105|
73
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:10:23.656|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
74
- 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:10:24.658|58=test_client initiate logout|10=105|
75
- 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:10:24.660|58=test_server confirming logout|10=081|
48
+ 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:05.877|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=045|
49
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:47:07.877|58=test_client initiate logout|10=120|
50
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:47:07.878|58=test_server confirming logout|10=104|
51
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:10.344|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=053|
52
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:10.346|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=153|
53
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:47:12.349|112=Sat, 15 Aug 2026 09:47:12 GMT|10=151|
54
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:47:14.351|112=Sat, 15 Aug 2026 09:47:14 GMT|10=149|
55
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260815-09:47:16.347|58=test_client initiate logout|10=113|
56
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:16.348|58=test_server confirming logout|10=095|
57
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:18.810|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
58
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:18.811|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=108|
59
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:20.817|112=Sat, 15 Aug 2026 09:47:20 GMT|10=149|
60
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:47:22.820|112=Sat, 15 Aug 2026 09:47:22 GMT|10=148|
61
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260815-09:47:24.822|112=Sat, 15 Aug 2026 09:47:24 GMT|10=155|
62
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:47:26.813|58=test_client initiate logout|10=110|
63
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260815-09:47:26.814|58=test_server confirming logout|10=097|
64
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:47:29.522|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=061|
65
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:47:29.524|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=114|
66
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:47:31.528|112=Sat, 15 Aug 2026 09:47:31 GMT|10=152|
67
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260815-09:47:33.530|112=Sat, 15 Aug 2026 09:47:33 GMT|10=150|
68
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:47:34.533|112=Sat, 15 Aug 2026 09:47:34 GMT|10=154|
69
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260815-09:47:35.531|112=Sat, 15 Aug 2026 09:47:35 GMT|10=156|
70
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260815-09:47:37.525|58=test_client initiate logout|10=115|
71
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260815-09:47:37.526|58=test_server confirming logout|10=097|
72
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260815-09:49:49.210|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
73
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260815-09:49:49.220|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=158|
74
+ 8=FIX.4.4|9=0000101|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260815-09:49:50.222|58=test_client initiate logout|10=103|
75
+ 8=FIX.4.4|9=0000103|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260815-09:49:50.224|58=test_server confirming logout|10=088|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspurefix",
3
- "version": "5.11.0",
3
+ "version": "5.11.1",
4
4
  "description": "pure node js fix engine",
5
5
  "keywords": [
6
6
  "typescript",
@@ -0,0 +1,56 @@
1
+ /**
2
+ * A readable reason for a failed connection.
3
+ *
4
+ * Node raises an AggregateError when the host resolved to more than one address and
5
+ * every attempt failed. That is not an edge case: 'localhost' is both ::1 and
6
+ * 127.0.0.1 on any modern machine, so it is what an ordinary refused connection looks
7
+ * like. Its own message is empty and the detail sits in errors[], so reporting
8
+ * e.message alone said nothing at all about the commonest failure there is - an
9
+ * application catching a rejected connect saw an Error with no message.
10
+ *
11
+ * Falls back to the code (ECONNREFUSED, ENOTFOUND, ETIMEDOUT) when there is no
12
+ * message anywhere, which is still enough to act on.
13
+ */
14
+ export function describeConnectError (e: unknown): string {
15
+ if (e == null) return 'unknown error'
16
+ const described = detail(e)
17
+ return described.length > 0 ? described : String(e)
18
+ }
19
+
20
+ /**
21
+ * The reason, or '' when this error carries none.
22
+ *
23
+ * Kept separate from the public function so a nested error with nothing to say
24
+ * contributes nothing, rather than a stringified 'Error' that would then look like a
25
+ * reason and stop the aggregate falling back to its own code.
26
+ */
27
+ function detail (e: unknown): string {
28
+ if (e == null) return ''
29
+
30
+ const err = e as { message?: string, code?: string, errors?: unknown[] }
31
+
32
+ if (Array.isArray(err.errors) && err.errors.length > 0) {
33
+ // every address usually fails the same way - say it once rather than repeating
34
+ // 'connect ECONNREFUSED' for each family
35
+ const unique = Array.from(new Set(err.errors.map(detail).filter(m => m.length > 0)))
36
+ if (unique.length > 0) return unique.join('; ')
37
+ }
38
+
39
+ if (err.message) return err.message
40
+ if (err.code) return err.code
41
+ return ''
42
+ }
43
+
44
+ /**
45
+ * Give an error a message when it has none, keeping the object itself.
46
+ *
47
+ * Deliberately not a wrapper: `code` and `errors` are what a caller switches on, and
48
+ * building a fresh Error to hold the text would throw both away. Returns the same
49
+ * error so it can be used inline.
50
+ */
51
+ export function withConnectReason (e: Error): Error {
52
+ if (!e.message) {
53
+ e.message = describeConnectError(e)
54
+ }
55
+ return e
56
+ }
@@ -9,6 +9,7 @@ import { DITokens } from '../../runtime/di-tokens'
9
9
  import { ITcpTransportDescription } from './tcp-transport-description'
10
10
  import { IMsgApplication } from '../msg-application'
11
11
  import { FixEntity } from '../fix-entity'
12
+ import { describeConnectError } from './connect-error'
12
13
 
13
14
  /*
14
15
  create one application session instance - and recover a lost transport. Hence, the application
@@ -163,7 +164,7 @@ export class RecoveringTcpInitiator extends FixEntity {
163
164
  this.connect(this.connectTimeoutSecs).then(t => {
164
165
  this.logger.info(`new transport ${t.id}`)
165
166
  }).catch((e) => {
166
- this.logger.info(`failed to re-connect ${e.message} - backoff for ${this.backoffFailConnectSecs}`)
167
+ this.logger.info(`failed to re-connect: ${describeConnectError(e)} - backoff for ${this.backoffFailConnectSecs}`)
167
168
  this.th = setTimeout(() => {
168
169
  this.logger.info('returning to recover()')
169
170
  setImmediate(() => {
@@ -4,12 +4,12 @@ import { MsgTransport } from '../factory'
4
4
  import { IJsFixConfig, IJsFixLogger } from '../../config'
5
5
  import { TcpDuplex, FixDuplex } from '../duplex'
6
6
 
7
- import * as util from 'util'
8
7
  import { connect as tlsConnect, ConnectionOptions, TLSSocket } from 'tls'
9
8
  import { createConnection } from 'net'
10
9
  import Timeout = NodeJS.Timeout
11
10
  import { TlsOptionsFactory } from './tls-options-factory'
12
11
  import { describeConnectionOptions, describeNegotiated, describePeerCertificate } from './tls-diagnostics'
12
+ import { describeConnectError, withConnectReason } from './connect-error'
13
13
  import { inject, injectable } from 'tsyringe'
14
14
  import { DITokens } from '../../runtime/di-tokens'
15
15
  import { ITcpTransportDescription } from './tcp-transport-description'
@@ -74,7 +74,7 @@ export class TcpInitiator extends FixInitiator {
74
74
  // connect() whose timeout expires before the first retry interval fires - the
75
75
  // default case, timeout and reconnectSeconds are both 5 - reported a generic
76
76
  // "timeout whilst connecting" and threw away the reason. see #94.
77
- this.logger.info(`first connect attempt failed: ${first.message}`)
77
+ this.logger.info(`first connect attempt failed: ${describeConnectError(first)}`)
78
78
  this.repeatConnect(timeoutSeconds, first)
79
79
  .then((t: MsgTransport) => { resolve(t) })
80
80
  .catch((e: Error) => { reject(e) })
@@ -212,7 +212,7 @@ export class TcpInitiator extends FixInitiator {
212
212
  resolve(t)
213
213
  }).catch((e: Error) => {
214
214
  lastError = e
215
- this.logger.info(`${name}: retries ${retries} ${e.message}`)
215
+ this.logger.info(`${name}: retries ${retries} ${describeConnectError(e)}`)
216
216
  })
217
217
  }, reconnectSeconds * 1000)
218
218
  // a plain timer, not a promisified one: promisify(setTimeout) hands back no
@@ -223,7 +223,10 @@ export class TcpInitiator extends FixInitiator {
223
223
  this.timeoutTh = setTimeout(() => {
224
224
  this.clearTimer()
225
225
  this.state = InitiatorState.Stopped
226
- const e = lastError ?? new Error(`${name}: timeout of ${timeoutSeconds} whilst connecting`)
226
+ // this error is what the application catches from run() - so give it a message
227
+ // it can print. An AggregateError arrives with none at all, which meant a
228
+ // caller handling a failed connect had nothing to report but an empty string.
229
+ const e = withConnectReason(lastError ?? new Error(`${name}: timeout of ${timeoutSeconds} whilst connecting`))
227
230
  this.logger.warning(`${name}: giving up after ${timeoutSeconds}s and ${retries} retries, last error: ${e.message}`)
228
231
  reject(e)
229
232
  }, timeoutSeconds * 1000)