fix(quick-261005-d5d): Postfach-Abruf ueber EWS mit 60-s-Zeitgrenze
Gleicher eigener Timer wie im Kalender; httpreqs timeout greift waehrend des Verbindungsaufbaus nicht. 60 s, weil PDF-Anhaenge geladen werden. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,4 +10,4 @@ date: 2026-10-05
|
|||||||
- `CalendarSourceUnreachableError` + `isNetworkUnreachableError` (calendar.service.ts); `testConnection`/`testConnectionFromConfig` liefern `error: 'unreachable'`, lastSyncError „Server not reachable“.
|
- `CalendarSourceUnreachableError` + `isNetworkUnreachableError` (calendar.service.ts); `testConnection`/`testConnectionFromConfig` liefern `error: 'unreachable'`, lastSyncError „Server not reachable“.
|
||||||
- Formular: `formTestUnreachable` statt `formTestFailed`.
|
- Formular: `formTestUnreachable` statt `formTestFailed`.
|
||||||
- Nachweis (lokaler Container, kompilierter Provider): 172.16.0.3 -> nicht erreichbar nach 15,0 s; owa.ctl.de mit falschem Passwort -> erreichbar/abgelehnt 0,0 s. Tests api 2219+, web 1372 gruen.
|
- Nachweis (lokaler Container, kompilierter Provider): 172.16.0.3 -> nicht erreichbar nach 15,0 s; owa.ctl.de mit falschem Passwort -> erreichbar/abgelehnt 0,0 s. Tests api 2219+, web 1372 gruen.
|
||||||
- Gleiches Muster steckt in `inbox/exchange-inbox.provider.ts` (eigenes httpntlm ohne Zeitgrenze) — nicht angefasst.
|
- Nachtrag (User „fix“): `inbox/exchange-inbox.provider.ts` bekommt denselben Timer, 60 s (laedt PDF-Anhaenge). testConnection meldet dann „EWS server not reachable (no answer within 60 s)“. Unit-Test mit Fake-Timern; echter Lauf nicht wiederholt (gleiche Mechanik wie im Kalender, dort echt gemessen).
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ Diese Liste beschreibt in einfachen Worten, was sich von Version zu Version an T
|
|||||||
### Behoben
|
### Behoben
|
||||||
|
|
||||||
- Kalender (Exchange): Ist der Exchange-Server nicht erreichbar, bricht „Verbindung testen“ jetzt nach 15 Sekunden ab, statt rund zwei Minuten auf „Verbindung wird geprüft …“ zu stehen, und meldet „Der Kalender-Server ist nicht erreichbar“ statt des Hinweises auf Adresse und Zugangsdaten. Auch der regelmäßige Abruf im Hintergrund wartet nicht mehr länger als 15 Sekunden.
|
- Kalender (Exchange): Ist der Exchange-Server nicht erreichbar, bricht „Verbindung testen“ jetzt nach 15 Sekunden ab, statt rund zwei Minuten auf „Verbindung wird geprüft …“ zu stehen, und meldet „Der Kalender-Server ist nicht erreichbar“ statt des Hinweises auf Adresse und Zugangsdaten. Auch der regelmäßige Abruf im Hintergrund wartet nicht mehr länger als 15 Sekunden.
|
||||||
|
- Postfach-Abruf über Exchange (E-Mail-Alarme, PDF-Anhänge): Ein nicht erreichbarer Exchange-Server blockiert den Abruf und den Verbindungstest nicht mehr minutenlang, sondern höchstens 60 Sekunden.
|
||||||
- Links in Notiz-Kacheln öffnen jetzt immer in einem neuen Tab, statt das Dashboard im selben Fenster zu verlassen. In der Desktop-App öffnen sie wie gewohnt im Browser.
|
- Links in Notiz-Kacheln öffnen jetzt immer in einem neuen Tab, statt das Dashboard im selben Fenster zu verlassen. In der Desktop-App öffnen sie wie gewohnt im Browser.
|
||||||
|
|
||||||
## 1.9.2 – 2026-10-02
|
## 1.9.2 – 2026-10-02
|
||||||
|
|||||||
@@ -128,6 +128,24 @@ beforeEach(() => {
|
|||||||
httpntlmPost.mockClear();
|
httpntlmPost.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('ExchangeInboxProvider — Zeitgrenze (quick-261005)', () => {
|
||||||
|
it('testConnection meldet nach 60 s ohne Antwort „nicht erreichbar“ statt zu haengen', async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
try {
|
||||||
|
httpntlmPost.mockImplementation(() => {
|
||||||
|
/* ruft nie zurueck — wie ein unbeantworteter Verbindungsaufbau */
|
||||||
|
});
|
||||||
|
const pending = new ExchangeInboxProvider().testConnection(BASE_CONFIG);
|
||||||
|
await vi.advanceTimersByTimeAsync(60_000);
|
||||||
|
const result = await pending;
|
||||||
|
expect(result.success).toBe(false);
|
||||||
|
expect(result.message).toContain('not reachable');
|
||||||
|
} finally {
|
||||||
|
vi.useRealTimers();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('ExchangeInboxProvider.fetchMessages', () => {
|
describe('ExchangeInboxProvider.fetchMessages', () => {
|
||||||
it('a BodyType="HTML" GetItem response yields bodyHtml populated and bodyText empty', async () => {
|
it('a BodyType="HTML" GetItem response yields bodyHtml populated and bodyText empty', async () => {
|
||||||
mockEwsFlow(getItemHtmlResponse());
|
mockEwsFlow(getItemHtmlResponse());
|
||||||
|
|||||||
@@ -258,9 +258,28 @@ interface NtlmResponse {
|
|||||||
body?: Buffer | string;
|
body?: Buffer | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* quick-261005: Obergrenze je EWS-Aufruf. Ohne sie wartete ein Aufruf auf
|
||||||
|
* eine nicht erreichbare Adresse rund zwei Minuten. 60 s statt der 15 s im
|
||||||
|
* Kalender, weil hier auch PDF-Anhaenge geladen werden.
|
||||||
|
*/
|
||||||
|
const INBOX_EWS_TIMEOUT_MS = 60_000;
|
||||||
|
|
||||||
function ntlmPost(opts: NtlmOptions): Promise<{ statusCode: number; body: string }> {
|
function ntlmPost(opts: NtlmOptions): Promise<{ statusCode: number; body: string }> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
// Eigener Timer statt httpreqs `timeout`: dessen Leerlaufgrenze greift
|
||||||
|
// waehrend des Verbindungsaufbaus ueber den Keep-alive-Agenten von
|
||||||
|
// httpntlm nicht (gemessen 05.10., siehe calendar/providers/exchange.provider.ts).
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
reject(
|
||||||
|
Object.assign(
|
||||||
|
new Error(`EWS server not reachable (no answer within ${INBOX_EWS_TIMEOUT_MS / 1000} s)`),
|
||||||
|
{ code: 'TIMEOUT' },
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}, INBOX_EWS_TIMEOUT_MS);
|
||||||
httpntlm.post(opts, (err, res) => {
|
httpntlm.post(opts, (err, res) => {
|
||||||
|
clearTimeout(timer);
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
resolve({
|
resolve({
|
||||||
statusCode: res.statusCode,
|
statusCode: res.statusCode,
|
||||||
|
|||||||
Reference in New Issue
Block a user