Skip to content

Commit 48698e1

Browse files
Awakichclaude
andcommitted
add error handling for infinite scroll & file uploads, fix 401 in FileService
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f858f42 commit 48698e1

File tree

9 files changed

+96
-21
lines changed

9 files changed

+96
-21
lines changed

projects/social_platform/src/app/core/services/file.service.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { Injectable } from "@angular/core";
44
import { ApiService, TokenService } from "@corelib";
5-
import { Observable } from "rxjs";
5+
import { firstValueFrom, Observable } from "rxjs";
66
import { HttpParams } from "@angular/common/http";
77
import { environment } from "@environment";
88

@@ -32,17 +32,36 @@ export class FileService {
3232
const formData = new FormData();
3333
formData.append("file", file);
3434

35-
return new Observable<{ url: string }>(observer => {
35+
const doFetch = (token: string) =>
3636
fetch(`${environment.apiUrl}${this.FILES_URL}/`, {
3737
method: "POST",
38-
headers: {
39-
Authorization: `Bearer ${this.tokenService.getTokens()?.access}`,
40-
},
38+
headers: { Authorization: `Bearer ${token}` },
4139
body: formData,
42-
})
43-
.then(res => res.json())
44-
.then(res => {
45-
observer.next(res);
40+
});
41+
42+
return new Observable<{ url: string }>(observer => {
43+
const execute = async () => {
44+
const token = this.tokenService.getTokens()?.access;
45+
if (!token) throw new Error("No access token");
46+
47+
let res = await doFetch(token);
48+
49+
if (res.status === 401) {
50+
const refreshRes = await firstValueFrom(this.tokenService.refreshTokens());
51+
this.tokenService.memTokens(refreshRes);
52+
res = await doFetch(refreshRes.access);
53+
}
54+
55+
if (!res.ok) {
56+
throw new Error(`Upload failed: ${res.status}`);
57+
}
58+
59+
return res.json();
60+
};
61+
62+
execute()
63+
.then(data => {
64+
observer.next(data);
4665
observer.complete();
4766
})
4867
.catch(err => observer.error(err));

projects/social_platform/src/app/office/features/news-card/news-card.component.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { FileService } from "@core/services/file.service";
2525
import { nanoid } from "nanoid";
2626
import { expandElement } from "@utils/expand-element";
2727
import { FileModel } from "@models/file.model";
28-
import { forkJoin, noop, Observable, tap } from "rxjs";
28+
import { catchError, forkJoin, noop, Observable, of, tap } from "rxjs";
2929
import { ButtonComponent, IconComponent } from "@ui/components";
3030
import { FileItemComponent } from "@ui/components/file-item/file-item.component";
3131
import { FileUploadItemComponent } from "@ui/components/file-upload-item/file-upload-item.component";
@@ -279,6 +279,11 @@ export class NewsCardComponent implements OnInit {
279279
fileObj.src = file.url;
280280
fileObj.loading = false;
281281
fileObj.tempFile = null;
282+
}),
283+
catchError(() => {
284+
fileObj.loading = false;
285+
fileObj.error = true;
286+
return of(null);
282287
})
283288
)
284289
);
@@ -301,6 +306,11 @@ export class NewsCardComponent implements OnInit {
301306
fileObj.loading = false;
302307
fileObj.src = file.url;
303308
fileObj.tempFile = null;
309+
}),
310+
catchError(() => {
311+
fileObj.loading = false;
312+
fileObj.error = "Ошибка загрузки";
313+
return of(null);
304314
})
305315
)
306316
);

projects/social_platform/src/app/office/features/news-form/news-form.component.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from "@angula
55
import { ValidationService } from "projects/core";
66
import { nanoid } from "nanoid";
77
import { FileService } from "@core/services/file.service";
8-
import { forkJoin, noop, Observable, tap } from "rxjs";
8+
import { catchError, forkJoin, noop, Observable, of, tap } from "rxjs";
99
import { FileUploadItemComponent } from "@ui/components/file-upload-item/file-upload-item.component";
1010
import { IconComponent, InputComponent } from "@ui/components";
1111
import { AutosizeModule } from "ngx-autosize";
@@ -76,13 +76,16 @@ export class NewsFormComponent implements OnInit {
7676
...this.messageForm.value,
7777
files: [...this.imagesList.map(f => f.src), ...this.filesList.map(f => f.src)],
7878
});
79+
80+
this.onResetForm();
7981
}
8082

8183
/**
8284
* Сброс формы и очистка списков файлов
8385
*/
8486
onResetForm() {
8587
this.imagesList = [];
88+
this.filesList = [];
8689
this.messageForm.reset();
8790
}
8891

@@ -128,6 +131,11 @@ export class NewsFormComponent implements OnInit {
128131
fileObj.src = file.url;
129132
fileObj.loading = false;
130133
fileObj.tempFile = null;
134+
}),
135+
catchError(() => {
136+
fileObj.loading = false;
137+
fileObj.error = true;
138+
return of(null);
131139
})
132140
)
133141
);
@@ -145,6 +153,11 @@ export class NewsFormComponent implements OnInit {
145153
tap(file => {
146154
fileObj.loading = false;
147155
fileObj.src = file.url;
156+
}),
157+
catchError(() => {
158+
fileObj.loading = false;
159+
fileObj.error = "Ошибка загрузки";
160+
return of(null);
148161
})
149162
)
150163
);

projects/social_platform/src/app/office/feed/feed.component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,18 @@ import { CommonModule } from "@angular/common";
1515
import { NewProjectComponent } from "@office/feed/shared/new-project/new-project.component";
1616
import { ActivatedRoute } from "@angular/router";
1717
import { FeedItem, FeedItemType } from "@office/feed/models/feed-item.model";
18-
import { concatMap, fromEvent, map, noop, of, skip, Subscription, tap, throttleTime } from "rxjs";
18+
import {
19+
catchError,
20+
concatMap,
21+
fromEvent,
22+
map,
23+
noop,
24+
of,
25+
skip,
26+
Subscription,
27+
tap,
28+
throttleTime,
29+
} from "rxjs";
1930
import { ApiPagination } from "@models/api-pagination.model";
2031
import { FeedService } from "@office/feed/services/feed.service";
2132
import { ProjectNewsService } from "@office/projects/detail/services/project-news.service";
@@ -99,7 +110,7 @@ export class FeedComponent implements OnInit, AfterViewInit, OnDestroy {
99110
if (target) {
100111
const scrollEvents$ = fromEvent(target, "scroll")
101112
.pipe(
102-
concatMap(() => this.onScroll()),
113+
concatMap(() => this.onScroll().pipe(catchError(() => of({})))),
103114
throttleTime(500)
104115
)
105116
.subscribe(noop);

projects/social_platform/src/app/office/members/members.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { ActivatedRoute, Router, RouterLink } from "@angular/router";
1515
import {
1616
BehaviorSubject,
17+
catchError,
1718
concatMap,
1819
debounceTime,
1920
distinctUntilChanged,
@@ -204,8 +205,8 @@ export class MembersComponent implements OnInit, OnDestroy, AfterViewInit {
204205
if (target) {
205206
const scrollEvents$ = fromEvent(target, "scroll")
206207
.pipe(
207-
concatMap(() => this.onScroll()),
208-
throttleTime(500) // Ограничиваем частоту обработки прокрутки
208+
concatMap(() => this.onScroll().pipe(catchError(() => of({})))),
209+
throttleTime(500)
209210
)
210211
.subscribe(noop);
211212

projects/social_platform/src/app/office/mentors/mentors.component.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,23 @@ import {
1111
ViewChild,
1212
} from "@angular/core";
1313
import { ActivatedRoute, RouterLink } from "@angular/router";
14-
import { concatMap, fromEvent, map, noop, of, Subscription, tap, throttleTime } from "rxjs";
14+
import {
15+
catchError,
16+
concatMap,
17+
fromEvent,
18+
map,
19+
noop,
20+
of,
21+
Subscription,
22+
tap,
23+
throttleTime,
24+
} from "rxjs";
1525
import { AuthService } from "@auth/services";
1626
import { User } from "@auth/models/user.model";
1727
import { NavService } from "@services/nav.service";
1828
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
1929
import { containerSm } from "@utils/responsive";
2030
import { MemberService } from "@services/member.service";
21-
import { MemberCardComponent } from "../shared/member-card/member-card.component";
2231
import { ApiPagination } from "@models/api-pagination.model";
2332

2433
/**
@@ -99,7 +108,7 @@ export class MentorsComponent implements OnInit, OnDestroy, AfterViewInit {
99108
if (target)
100109
fromEvent(target, "scroll")
101110
.pipe(
102-
concatMap(() => this.onScroll()),
111+
concatMap(() => this.onScroll().pipe(catchError(() => of({})))),
103112
throttleTime(500)
104113
)
105114
.subscribe(noop);

projects/social_platform/src/app/office/program/detail/shared/news-card/news-card.component.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { expandElement } from "@utils/expand-element";
1818
import { FileModel } from "@office/models/file.model";
1919
import { nanoid } from "nanoid";
2020
import { FileService } from "@core/services/file.service";
21-
import { forkJoin, noop, Observable, tap } from "rxjs";
21+
import { catchError, forkJoin, noop, Observable, of, tap } from "rxjs";
2222
import { DayjsPipe, FormControlPipe, ParseLinksPipe, ValidationService } from "projects/core";
2323
import { FileItemComponent } from "@ui/components/file-item/file-item.component";
2424
import { ButtonComponent, IconComponent } from "@ui/components";
@@ -266,6 +266,11 @@ export class ProgramNewsCardComponent implements OnInit, AfterViewInit {
266266
fileObj.src = file.url;
267267
fileObj.loading = false;
268268
fileObj.tempFile = null;
269+
}),
270+
catchError(() => {
271+
fileObj.loading = false;
272+
fileObj.error = true;
273+
return of(null);
269274
})
270275
)
271276
);
@@ -288,6 +293,11 @@ export class ProgramNewsCardComponent implements OnInit, AfterViewInit {
288293
fileObj.loading = false;
289294
fileObj.src = file.url;
290295
fileObj.tempFile = null;
296+
}),
297+
catchError(() => {
298+
fileObj.loading = false;
299+
fileObj.error = "Ошибка загрузки";
300+
return of(null);
291301
})
292302
)
293303
);

projects/social_platform/src/app/office/projects/list/list.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from "@angular/core";
1414
import { ActivatedRoute, NavigationEnd, Params, Router, RouterLink } from "@angular/router";
1515
import {
16+
catchError,
1617
concatMap,
1718
distinctUntilChanged,
1819
fromEvent,
@@ -192,7 +193,7 @@ export class ProjectsListComponent implements OnInit, AfterViewInit, OnDestroy {
192193
if (target) {
193194
const scrollEvent$ = fromEvent(target, "scroll")
194195
.pipe(
195-
concatMap(() => this.onScroll()),
196+
concatMap(() => this.onScroll().pipe(catchError(() => of({})))),
196197
throttleTime(500)
197198
)
198199
.subscribe(noop);

projects/social_platform/src/app/office/vacancies/list/list.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { Component, inject, signal } from "@angular/core";
77
import { CommonModule } from "@angular/common";
88
import {
9+
catchError,
910
concatMap,
1011
debounceTime,
1112
fromEvent,
@@ -124,7 +125,7 @@ export class VacanciesListComponent {
124125
if (target) {
125126
const scrollEvents$ = fromEvent(target, "scroll")
126127
.pipe(
127-
concatMap(() => this.onScroll()),
128+
concatMap(() => this.onScroll().pipe(catchError(() => of({})))),
128129
throttleTime(500)
129130
)
130131
.subscribe(noop);

0 commit comments

Comments
 (0)