http.request()에서 예외를 올바르게 포착하려면 어떻게 해야 합니까?
코드의 일부:
import {Injectable} from 'angular2/core';
import {Http, Headers, Request, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@Injectable()
export class myClass {
constructor(protected http: Http) {}
public myMethod() {
let request = new Request({
method: "GET",
url: "http://my_url"
});
return this.http.request(request)
.map(res => res.json())
.catch(this.handleError); // Trouble line.
// Without this line code works perfectly.
}
public handleError(error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
myMethod()
는 브라우저 콘솔에서 예외를 생성합니다.
원래 예외: TypeError: this.http.request(...).map(...).catch는 함수가 아닙니다.
Import에 추가할 수 있습니다.
import 'rxjs/add/operator/catch';
다음 작업도 가능합니다.
return this.http.request(request)
.map(res => res.json())
.subscribe(
data => console.log(data),
err => console.log(err),
() => console.log('yay')
);
코멘트 단위:
예외: TypeError: Observable_1.관찰할 수 있다.투척은 함수가 아니다
마찬가지로 이를 위해 다음을 사용할 수 있습니다.
import 'rxjs/add/observable/throw';
HttpClientModule 및 RxJs v5.5.x를 사용하도록 새 서비스가 업데이트되었습니다.
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { catchError, tap } from 'rxjs/operators';
import { SomeClassOrInterface} from './interfaces';
import 'rxjs/add/observable/throw';
@Injectable()
export class MyService {
url = 'http://my_url';
constructor(private _http:HttpClient) {}
private handleError(operation: String) {
return (err: any) => {
let errMsg = `error in ${operation}() retrieving ${this.url}`;
console.log(`${errMsg}:`, err)
if(err instanceof HttpErrorResponse) {
// you could extract more info about the error if you want, e.g.:
console.log(`status: ${err.status}, ${err.statusText}`);
// errMsg = ...
}
return Observable.throw(errMsg);
}
}
// public API
public getData() : Observable<SomeClassOrInterface> {
// HttpClient.get() returns the body of the response as an untyped JSON object.
// We specify the type as SomeClassOrInterfaceto get a typed result.
return this._http.get<SomeClassOrInterface>(this.url)
.pipe(
tap(data => console.log('server data:', data)),
catchError(this.handleError('getData'))
);
}
사용되지 않는 Http Module을 사용하는 오래된 서비스:
import {Injectable} from 'angular2/core';
import {Http, Response, Request} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
//import 'rxjs/Rx'; // use this line if you want to be lazy, otherwise:
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do'; // debug
import 'rxjs/add/operator/catch';
@Injectable()
export class MyService {
constructor(private _http:Http) {}
private _serverError(err: any) {
console.log('sever error:', err); // debug
if(err instanceof Response) {
return Observable.throw(err.json().error || 'backend server error');
// if you're using lite-server, use the following line
// instead of the line above:
//return Observable.throw(err.text() || 'backend server error');
}
return Observable.throw(err || 'backend server error');
}
private _request = new Request({
method: "GET",
// change url to "./data/data.junk" to generate an error
url: "./data/data.json"
});
// public API
public getData() {
return this._http.request(this._request)
// modify file data.json to contain invalid JSON to have .json() raise an error
.map(res => res.json()) // could raise an error if invalid JSON
.do(data => console.log('server data:', data)) // debug
.catch(this._serverError);
}
}
사용하고 있다.do()
( now ) 디버깅에 사용합니다.
서버 에러가 발생했을 때body
의Response
사용하고 있는 서버로부터 취득한 오브젝트(라이트 서버)에는 텍스트만 포함되어 있기 때문에 사용하는 이유err.text()
보다 위에err.json().error
서버의 회선을 조정할 필요가 있는 경우가 있습니다.
한다면res.json()
JSON 데이터를 해석할 수 없었기 때문에 에러가 발생합니다._serverError
을 얻을 수 없다Response
오브젝트, 그 이유는instanceof
확인.
이 경우 변경한다.url
로../data/data.junk
에러를 생성합니다.
어느 서비스 사용자도 오류를 처리할 수 있는 코드를 가지고 있어야 합니다.
@Component({
selector: 'my-app',
template: '<div>{{data}}</div>
<div>{{errorMsg}}</div>`
})
export class AppComponent {
errorMsg: string;
constructor(private _myService: MyService ) {}
ngOnInit() {
this._myService.getData()
.subscribe(
data => this.data = data,
err => this.errorMsg = <any>err
);
}
}
여기에는 몇 가지 방법이 있습니다.둘 다 매우 간단합니다.각각의 예는 훌륭하게 기능합니다.프로젝트에 복사하여 테스트할 수 있습니다.
첫 번째 방법이 더 바람직하고 두 번째 방법이 좀 구식이지만 아직까지는 효과가 있습니다.
1) 솔루션 1
// File - app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { ProductService } from './product.service';
import { ProductModule } from './product.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [ProductService, ProductModule],
bootstrap: [AppComponent]
})
export class AppModule { }
// File - product.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
// Importing rxjs
import 'rxjs/Rx';
import { Observable } from 'rxjs/Rx';
import { catchError, tap } from 'rxjs/operators'; // Important! Be sure to connect operators
// There may be your any object. For example, we will have a product object
import { ProductModule } from './product.module';
@Injectable()
export class ProductService{
// Initialize the properties.
constructor(private http: HttpClient, private product: ProductModule){}
// If there are no errors, then the object will be returned with the product data.
// And if there are errors, we will get into catchError and catch them.
getProducts(): Observable<ProductModule[]>{
const url = 'YOUR URL HERE';
return this.http.get<ProductModule[]>(url).pipe(
tap((data: any) => {
console.log(data);
}),
catchError((err) => {
throw 'Error in source. Details: ' + err; // Use console.log(err) for detail
})
);
}
}
2) 솔루션 2.오래된 방식이지만 여전히 효과가 있다.
// File - app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { ProductService } from './product.service';
import { ProductModule } from './product.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule
],
providers: [ProductService, ProductModule],
bootstrap: [AppComponent]
})
export class AppModule { }
// File - product.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
// Importing rxjs
import 'rxjs/Rx';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class ProductService{
// Initialize the properties.
constructor(private http: Http){}
// If there are no errors, then the object will be returned with the product data.
// And if there are errors, we will to into catch section and catch error.
getProducts(){
const url = '';
return this.http.get(url).map(
(response: Response) => {
const data = response.json();
console.log(data);
return data;
}
).catch(
(error: Response) => {
console.log(error);
return Observable.throw(error);
}
);
}
}
RxJs 함수는 구체적으로 Import해야 합니다.이를 위한 간단한 방법은 모든 기능을 Import하는 것입니다.import * as Rx from "rxjs/Rx"
그럼 꼭 접속해 주세요.Observable
로 분류하다.Rx.Observable
.
최신 버전의 angular4 사용
import { Observable } from 'rxjs/Rx'
필요한 모든 것을 가져옵니다.
언급URL : https://stackoverflow.com/questions/35326689/how-to-catch-exception-correctly-from-http-request
'source' 카테고리의 다른 글
처음 활성화될 때만 실행되는 플러그인에 코드를 추가하시겠습니까? (0) | 2023.02.10 |
---|---|
기본적으로 Oracle 주문 NULL LAST (0) | 2023.02.10 |
Visual Studio에 설치된 TypeScript 버전은 어디서 찾을 수 있습니까? (0) | 2023.02.10 |
Spring Data Maven Builds의 "플러그인 실행은 라이프 사이클 구성에 포함되지 않음" 문제 해결 방법 (0) | 2023.02.10 |
React JS - 다른 컴포넌트에서 컴포넌트 메서드 호출 (0) | 2023.02.10 |