- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
显然 throwError(error)
现在已弃用。 VS Code 的 IntelliSense 建议 throwError(() => new Error('error')
. new Error(...)
只接受字符串。在不破坏我的 HttpErrorHandlerService
的情况下更换它的正确方法是什么? ?
http-error.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpErrorResponse,
HttpResponse,
HttpHeaders
} from '@angular/common/http';
import { Observable, EMPTY, finalize, catchError, timeout, map, throwError } from 'rxjs';
import { HttpErrorHandlerService } from '@core/services';
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
private readonly APP_XHR_TIMEOUT = 6000;
constructor(private errorHandlerService: HttpErrorHandlerService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(this.performRequest(request)).pipe(
timeout(this.APP_XHR_TIMEOUT),
map((event: HttpEvent<any>) => this.handleSuccessfulResponse(event)),
catchError((error: HttpErrorResponse) => this.processRequestError(error, request, next)),
finalize(this.handleRequestCompleted.bind(this))
);
}
private performRequest(request: HttpRequest<any>): HttpRequest<any> {
let headers: HttpHeaders = request.headers;
//headers = headers.set('MyCustomHeaderKey', `MyCustomHeaderValue`);
return request.clone({ headers });
}
private handleSuccessfulResponse(event: HttpEvent<any>): HttpEvent<any> {
if (event instanceof HttpResponse) {
event = event.clone({ body: event.body.response });
}
return event;
}
private processRequestError(
error: HttpErrorResponse,
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
console.log('http error response');
if ([401].includes(error.status)) {
return throwError(error);
}
this.errorHandlerService.handle(error);
return throwError(error);
}
private handleRequestCompleted(): void {
// console.log(`Request finished`);
}
}
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { MessageService } from 'primeng/api';
import { TimeoutError } from 'rxjs';
/**
* Shows a user-friendly error message when a HTTP request fails.
*/
@Injectable({
providedIn: 'root'
})
export class HttpErrorHandlerService {
constructor(private messageService: MessageService) {}
handle(error: Error | HttpErrorResponse) {
if (error instanceof TimeoutError) {
return this.openDialog('error', `Няма връзка до сървъра.`);
}
if (error instanceof HttpErrorResponse && error.error && error.error.message) {
return this.openDialog('error', error.error.message);
}
if (error instanceof Error) {
switch (error.message) {
default:
return this.openDialog('error', `An unknown error occurred`);
}
}
// Generic HTTP errors
switch (error.status) {
case 400:
switch (error.error) {
case 'invalid_username_or_password':
return this.openDialog('error', 'Невалидно потребителско име или парола');
default:
return this.openDialog('error', 'Bad request');
}
case 401:
return this.openDialog('error', 'Ще трябва да се логнете отново');
case 403:
return this.openDialog('error', `You don't have the required permissions`);
case 404:
return this.openDialog('error', 'Resource not found');
case 422:
return this.openDialog('error', 'Invalid data provided');
case 500:
case 501:
case 502:
case 503:
return this.openDialog('error', 'An internal server error occurred');
case -1:
return this.openDialog(
'error',
'You appear to be offline. Please check your internet connection and try again.'
);
case 0:
return this.openDialog('error', `CORS issue?`);
default:
return this.openDialog('error', `An unknown error occurred`);
}
}
private openDialog(severity: string, message: string) {
if (message?.trim()) {
this.messageService.add({
key: 'interceptor',
severity: severity,
summary: 'Информация',
detail: message,
life: 3000
});
}
}
}
auth.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse
} from '@angular/common/http';
import {
BehaviorSubject,
catchError,
EMPTY,
filter,
finalize,
Observable,
switchMap,
take,
throwError
} from 'rxjs';
import { AuthService } from '@core/services';
import { AuthResponse } from '@core/types';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
private refreshTokenInProgress: boolean;
private refreshToken$ = new BehaviorSubject<AuthResponse | null>(null);
constructor(private authService: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next
.handle(this.performRequest(request))
.pipe(
catchError((error: HttpErrorResponse) => this.processRequestError(error, request, next))
);
}
private performRequest(request: HttpRequest<any>): HttpRequest<any> {
const accessToken = this.authService.getAccessToken();
let headers = request.headers;
if (accessToken) {
headers = headers.set('Authorization', `Bearer ${accessToken}`);
}
return request.clone({ headers });
}
private processRequestError(
error: HttpErrorResponse,
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
console.log('auth interceptor called');
if (
error instanceof HttpErrorResponse &&
error.status === 401 &&
this.authService.isSignedIn()
) {
return this.refreshToken(request, next);
}
return throwError(error);
}
private refreshToken(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('refresh token in auth.interceptor called');
// in case the page consists of more than one requests
if (!this.refreshTokenInProgress) {
this.refreshToken$.next(null);
this.refreshTokenInProgress = true;
return this.authService.refreshToken().pipe(
switchMap((response) => {
if (response) {
this.refreshToken$.next(response);
return next.handle(this.performRequest(request));
}
this.authService.signOut();
return throwError(() => new Error("RefreshTokenFailed"));
}),
catchError((error) => {
this.authService.signOut();
return throwError(error);
}),
finalize(() => (this.refreshTokenInProgress = false))
);
} else {
// wait while getting new token
return this.refreshToken$.pipe(
filter((result) => result !== null),
take(1),
switchMap(() => next.handle(this.performRequest(request)))
);
}
}
}
最佳答案
取而代之的是:
catchError((error) => {
this.authService.signOut();
return throwError(error);
}),
你可以试试这个:
catchError((error) => {
this.authService.signOut();
return throwError(() => error);
}),
我无法彻底测试它,但一个简单的尝试似乎奏效了。
getProducts(): Observable<IProduct[]> {
return this.http.get<IProduct[]>(this.productUrl)
.pipe(
tap(data => console.log('All: ', JSON.stringify(data))),
catchError(this.handleError)
);
}
private handleError(err: HttpErrorResponse): Observable<never> {
// just a test ... more could would go here
return throwError(() => err);
}
请注意
err
这是类型
HttpErrorResponse
.
ngOnInit(): void {
this.sub = this.productService.getProducts().subscribe({
next: products => {
this.products = products;
this.filteredProducts = this.products;
},
error: err => this.errorMessage = err.message
});
}
在这里,我能够检索到
message
错误响应中的属性并将其显示在我的 UI 中。
关于angular - throwError(error) 现在已弃用,但没有新的 Error(HttpErrorResponse),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68655492/
首先,我要明确一点,我知道 Rx throwError 运算符和 JS 的 throw 关键字的区别。我只是想知道为什么要使用 throwError 运算符?我通过创建一个新的 observable
正如预期的那样,以下代码在 5 秒后发出 42: const valueObservable = of(42).pipe(delay(5000)); valueObservable.subscribe
我创建了一个类并尝试调用一个方法,但是在我的 错误日志 , 我收到回复 "Uncaught Error: Call to undefined method Customersss::throwErro
我正在为一个函数编写测试,并且必须触发该函数的 .catch 部分,但 Jasmine 的 spy 出于某种原因不能这样做。待测方法: foo(){ doStuff() .catch((error)
Angular 文档谈到了一个“throwError”类,其导入语句如下所示 import { Observable, throwError } from 'rxjs'; 但我的编译器无法找到该类,并
显然 throwError(error)现在已弃用。 VS Code 的 IntelliSense 建议 throwError(() => new Error('error') . new Error
我正在尝试为 Node.js 构建一个简单的登录模块。我正在尝试以 TDD 方式进行操作,但我对它还是陌生的,所以任何有助于我更好地理解它的提示或资源都会很棒。 当我查询包含无效数据的数据库时,我的问
我想在我的订阅者上使用第二个参数(错误)但不起作用。 我的 Observable 代码: return Observable.create(obs => { cognitoidentityserv
目标:为服务器错误和应用程序错误(在 Typescript 代码中生成)提供全局错误处理程序。 如何:从同一工作空间内的 lib 项目中提供自定义 ErrorHandler。这是我的库结构: 我有以下
我正在使用 RxJS shareReplay()可观察对象( courses$ )上的运算符,以在其他两个可观察对象( beginnerCourses$ 和 advancedCourses$ )之间共
我是一名优秀的程序员,十分优秀!