Skip to content

Commit 9491bde

Browse files
Merge pull request #64 from justinhartman/develop
Merge the prevent home page crash on latest feed 403
2 parents df827a2 + 4c2fc70 commit 9491bde

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

controllers/appController.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,28 @@ describe('controllers/appController', () => {
9494
}));
9595
});
9696

97+
test('getHome handles upstream failures without crashing', async () => {
98+
(http.get as jest.Mock)
99+
.mockRejectedValueOnce(new Error('403'))
100+
.mockResolvedValueOnce({ data: { result: [{ imdb_id: '2' }] } });
101+
(fetchAndUpdatePosters as jest.Mock).mockResolvedValue(undefined);
102+
(getLatest as jest.Mock).mockReturnValue(undefined);
103+
104+
const req: any = { query: {}, user: {} };
105+
const res: any = {
106+
locals: { APP_URL: 'http://app', CARD_TYPE: 'card' },
107+
render: jest.fn(),
108+
};
109+
110+
await appController.getHome(req, res, jest.fn());
111+
112+
expect(setLatest).not.toHaveBeenCalled();
113+
expect(res.render).toHaveBeenCalledWith('index', expect.objectContaining({
114+
newMovies: [],
115+
newSeries: [{ imdb_id: '2' }],
116+
}));
117+
});
118+
97119
test('getHome returns cached results when available', async () => {
98120
(getLatest as jest.Mock).mockReturnValue({
99121
movies: [{ imdb_id: 'm1' }],

controllers/appController.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,35 @@ const appController = {
8282
});
8383
}
8484

85-
const [axiosMovieResponse, axiosSeriesResponse] = await Promise.all([
85+
const [movieResult, seriesResult] = await Promise.allSettled([
8686
http.get(`https://${appConfig.VIDSRC_DOMAIN}/movies/latest/page-1.json`),
8787
http.get(`https://${appConfig.VIDSRC_DOMAIN}/tvshows/latest/page-1.json`),
8888
]);
8989

90-
let newMovies = axiosMovieResponse.data.result || [];
91-
let newSeries = axiosSeriesResponse.data.result || [];
90+
let newMovies =
91+
movieResult.status === 'fulfilled' ? movieResult.value.data.result || [] : [];
92+
let newSeries =
93+
seriesResult.status === 'fulfilled' ? seriesResult.value.data.result || [] : [];
94+
95+
if (movieResult.status === 'rejected') {
96+
console.warn('Failed to fetch latest movies; continuing with empty dataset');
97+
}
98+
99+
if (seriesResult.status === 'rejected') {
100+
console.warn('Failed to fetch latest series; continuing with empty dataset');
101+
}
92102

93103
await Promise.all([
94104
fetchAndUpdatePosters(newMovies),
95105
fetchAndUpdatePosters(newSeries),
96106
]);
97107

98-
setLatest({ movies: newMovies, series: newSeries });
108+
const hasFeedFailure =
109+
movieResult.status === 'rejected' || seriesResult.status === 'rejected';
110+
111+
if (!hasFeedFailure) {
112+
setLatest({ movies: newMovies, series: newSeries });
113+
}
99114

100115
res.render('index', {
101116
newMovies,
@@ -132,7 +147,7 @@ const appController = {
132147
*/
133148
getView: asyncHandler(async (req: AuthRequest, res: Response) => {
134149
const query = req.params.q || '';
135-
const id = req.params.id;
150+
const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
136151
const type = req.params.type as 'movie' | 'series';
137152

138153
const cookieHeader =
@@ -143,8 +158,12 @@ const appController = {
143158
const preferredServer = match ? (match[1] as '1' | '2') : undefined;
144159

145160
if (type === 'series') {
146-
let season = req.params.season;
147-
let episode = req.params.episode;
161+
let season = Array.isArray(req.params.season)
162+
? req.params.season[0]
163+
: req.params.season;
164+
let episode = Array.isArray(req.params.episode)
165+
? req.params.episode[0]
166+
: req.params.episode;
148167

149168
if ((!season || !episode) && req.user) {
150169
const redirectTo = await getResumeRedirect(req.user.id, id);

0 commit comments

Comments
 (0)