Skip to content

Commit e168bfa

Browse files
Enhance getTodo method with retry logic and error handling for external API calls
1 parent 4fafd53 commit e168bfa

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

monolith/src/app.service.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
import { Injectable } from '@nestjs/common';
1+
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
22
import { ConfigService } from '@nestjs/config';
33

44
@Injectable()
55
export class AppService {
6+
private readonly maxRetries = 3;
7+
private readonly retryDelayMs = 1000;
8+
private readonly timeoutMs = 30000;
9+
610
constructor(private configService: ConfigService) {}
711

812
getHello(): string {
@@ -38,8 +42,49 @@ export class AppService {
3842
'TODOS_API_BASE_URL',
3943
'https://jsonplaceholder.typicode.com',
4044
);
41-
const response = await fetch(`${baseUrl}/todos/${id}`);
42-
return await response.json();
45+
46+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
47+
try {
48+
const controller = new AbortController();
49+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
50+
51+
const response = await fetch(`${baseUrl}/todos/${id}`, {
52+
signal: controller.signal,
53+
});
54+
55+
clearTimeout(timeoutId);
56+
57+
if (!response.ok) {
58+
if (response.status === 404) {
59+
throw new HttpException('Todo not found', HttpStatus.NOT_FOUND);
60+
}
61+
throw new Error(`HTTP error! status: ${response.status}`);
62+
}
63+
64+
const todo = await response.json();
65+
66+
if (!todo) {
67+
throw new HttpException('Todo not found', HttpStatus.NOT_FOUND);
68+
}
69+
70+
return todo;
71+
} catch (error) {
72+
if (error instanceof HttpException && error.getStatus() === HttpStatus.NOT_FOUND) {
73+
throw error;
74+
}
75+
76+
if (attempt === this.maxRetries - 1) {
77+
throw new HttpException(
78+
`External API is unavailable after ${this.maxRetries} attempts: ${error.message}`,
79+
HttpStatus.SERVICE_UNAVAILABLE,
80+
);
81+
}
82+
83+
await new Promise(resolve => setTimeout(resolve, this.retryDelayMs));
84+
}
85+
}
86+
87+
throw new HttpException('Unexpected error', HttpStatus.INTERNAL_SERVER_ERROR);
4388
}
4489

4590
getTodosPageHtml(): string {

0 commit comments

Comments
 (0)