Merge pull request #4805 from mempool/mononaut/http-error-handling
http error handling
This commit is contained in:
		
						commit
						1b21cd89a3
					
				| @ -98,11 +98,9 @@ | |||||||
|   </ng-template> |   </ng-template> | ||||||
| 
 | 
 | ||||||
|   <ng-template [ngIf]="error"> |   <ng-template [ngIf]="error"> | ||||||
|     <div class="text-center"> |     <app-http-error [error]="error"> | ||||||
|       Error loading address data. |       <span i18n="address.error.loading-address-data">Error loading address data.</span> | ||||||
|       <br> |     </app-http-error> | ||||||
|       <i>{{ error.error }}</i> |  | ||||||
|     </div> |  | ||||||
|   </ng-template> |   </ng-template> | ||||||
| 
 | 
 | ||||||
| </div> | </div> | ||||||
|  | |||||||
| @ -135,11 +135,10 @@ | |||||||
| 
 | 
 | ||||||
|   <ng-template [ngIf]="error"> |   <ng-template [ngIf]="error"> | ||||||
|     <br> |     <br> | ||||||
|  |     <ng-template [ngIf]="error.status === 413 || error.status === 405 || error.status === 504" [ngIfElse]="displayServerError"> | ||||||
|       <div class="text-center"> |       <div class="text-center"> | ||||||
|         <span i18n="address.error.loading-address-data">Error loading address data.</span> |         <span i18n="address.error.loading-address-data">Error loading address data.</span> | ||||||
|         <br> |         <br> | ||||||
|       <ng-template #displayServerError><i class="small">({{ error.error }})</i></ng-template> |  | ||||||
|       <ng-template [ngIf]="error.status === 413 || error.status === 405 || error.status === 504" [ngIfElse]="displayServerError"> |  | ||||||
|         <ng-container i18n="Electrum server limit exceeded error"> |         <ng-container i18n="Electrum server limit exceeded error"> | ||||||
|           <i>There many transactions on this address, more than your backend can handle. See more on <a href="/docs/faq#address-lookup-issues">setting up a stronger backend</a>.</i> |           <i>There many transactions on this address, more than your backend can handle. See more on <a href="/docs/faq#address-lookup-issues">setting up a stronger backend</a>.</i> | ||||||
|           <br><br> |           <br><br> | ||||||
| @ -150,10 +149,15 @@ | |||||||
|         <br> |         <br> | ||||||
|         <a href="http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/address/{{ addressString }}" target="_blank">http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/address/{{ addressString }}</a> |         <a href="http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/address/{{ addressString }}" target="_blank">http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/address/{{ addressString }}</a> | ||||||
|         <br><br> |         <br><br> | ||||||
|         <i class="small">({{ error.error }})</i> |         <i class="small">({{ error | httpErrorMsg }})</i> | ||||||
|       </ng-template> |  | ||||||
|       </div> |       </div> | ||||||
|     </ng-template> |     </ng-template> | ||||||
|  |     <ng-template #displayServerError> | ||||||
|  |       <app-http-error [error]="error"> | ||||||
|  |         <span i18n="address.error.loading-address-data">Error loading address data.</span> | ||||||
|  |       </app-http-error> | ||||||
|  |     </ng-template> | ||||||
|  |   </ng-template> | ||||||
| 
 | 
 | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -140,10 +140,22 @@ export class AddressComponent implements OnInit, OnDestroy { | |||||||
|           if (!fetchTxs.length) { |           if (!fetchTxs.length) { | ||||||
|             return of([]); |             return of([]); | ||||||
|           } |           } | ||||||
|           return this.apiService.getTransactionTimes$(fetchTxs); |           return this.apiService.getTransactionTimes$(fetchTxs).pipe( | ||||||
|  |             catchError((err) => { | ||||||
|  |               this.isLoadingAddress = false; | ||||||
|  |               this.isLoadingTransactions = false; | ||||||
|  |               this.error = err; | ||||||
|  |               this.seoService.logSoft404(); | ||||||
|  |               console.log(err); | ||||||
|  |               return of([]); | ||||||
|  |             }) | ||||||
|  |           ); | ||||||
|         }) |         }) | ||||||
|       ) |       ) | ||||||
|       .subscribe((times: number[]) => { |       .subscribe((times: number[] | null) => { | ||||||
|  |         if (!times) { | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|         times.forEach((time, index) => { |         times.forEach((time, index) => { | ||||||
|           this.tempTransactions[this.timeTxIndexes[index]].firstSeen = time; |           this.tempTransactions[this.timeTxIndexes[index]].firstSeen = time; | ||||||
|         }); |         }); | ||||||
|  | |||||||
| @ -146,13 +146,10 @@ | |||||||
|   </ng-template> |   </ng-template> | ||||||
| 
 | 
 | ||||||
|   <ng-template [ngIf]="error"> |   <ng-template [ngIf]="error"> | ||||||
|     <div class="text-center"> |     <app-http-error [error]="error"> | ||||||
|       <span i18n="asset.error.loading-asset-data">Error loading asset data.</span> |       <span i18n="asset.error.loading-asset-data">Error loading asset data.</span> | ||||||
|       <br> |     </app-http-error> | ||||||
|       <i>{{ error.error }}</i> |  | ||||||
|     </div> |  | ||||||
|   </ng-template> |   </ng-template> | ||||||
| 
 |  | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <br> | <br> | ||||||
|  | |||||||
| @ -46,9 +46,7 @@ | |||||||
| </ng-template> | </ng-template> | ||||||
| 
 | 
 | ||||||
| <ng-template [ngIf]="error"> | <ng-template [ngIf]="error"> | ||||||
|   <div class="text-center"> |   <app-http-error [error]="error"> | ||||||
|     <ng-container i18n="Asset data load error">Error loading assets data.</ng-container> |     <span i18n="Asset data load error">Error loading assets data.</span> | ||||||
|     <br> |   </app-http-error> | ||||||
|     <i>{{ error.error }}</i> |  | ||||||
|   </div> |  | ||||||
| </ng-template> | </ng-template> | ||||||
|  | |||||||
| @ -338,14 +338,12 @@ | |||||||
|     <app-transactions-list [transactions]="transactions" [paginated]="true" [blockTime]="block.timestamp"></app-transactions-list> |     <app-transactions-list [transactions]="transactions" [paginated]="true" [blockTime]="block.timestamp"></app-transactions-list> | ||||||
| 
 | 
 | ||||||
|     <ng-template [ngIf]="transactionsError"> |     <ng-template [ngIf]="transactionsError"> | ||||||
|       <div class="text-center"> |  | ||||||
|       <br> |       <br> | ||||||
|  |       <app-http-error [error]="transactionsError"> | ||||||
|         <span i18n="error.general-loading-data">Error loading data.</span> |         <span i18n="error.general-loading-data">Error loading data.</span> | ||||||
|         <br><br> |       </app-http-error> | ||||||
|         <i>{{ transactionsError.status }}: {{ transactionsError.error }}</i> |  | ||||||
|       <br> |       <br> | ||||||
|       <br> |       <br> | ||||||
|       </div> |  | ||||||
|     </ng-template> |     </ng-template> | ||||||
| 
 | 
 | ||||||
|     <ng-template [ngIf]="isLoadingTransactions && !transactionsError"> |     <ng-template [ngIf]="isLoadingTransactions && !transactionsError"> | ||||||
| @ -378,11 +376,9 @@ | |||||||
|     <br> |     <br> | ||||||
|   </ng-template> |   </ng-template> | ||||||
|   <ng-template [ngIf]="error"> |   <ng-template [ngIf]="error"> | ||||||
|     <div class="text-center"> |     <app-http-error [error]="error"> | ||||||
|       <span i18n="error.general-loading-data">Error loading data.</span> |       <span i18n="error.general-loading-data">Error loading data.</span> | ||||||
|       <br><br> |     </app-http-error> | ||||||
|       <i>{{ error.status }}: {{ error.error }}</i> |  | ||||||
|     </div> |  | ||||||
|   </ng-template> |   </ng-template> | ||||||
| 
 | 
 | ||||||
|   <ng-template #headerLoader> |   <ng-template #headerLoader> | ||||||
|  | |||||||
| @ -517,9 +517,9 @@ | |||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <ng-template #errorTemplate> |     <ng-template #errorTemplate> | ||||||
|       <div class="text-center"> |       <app-http-error [error]="error"> | ||||||
|         <h3>{{ error.error }}</h3> |         <span i18n="transaction.error.loading-transaction-data">Error loading transaction data.</span> | ||||||
|       </div> |       </app-http-error> | ||||||
|     </ng-template> |     </ng-template> | ||||||
|   </ng-template> |   </ng-template> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -66,9 +66,7 @@ | |||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <ng-template [ngIf]="error"> | <ng-template [ngIf]="error"> | ||||||
|   <div class="text-center"> |   <app-http-error [error]="error"> | ||||||
|     <span i18n="error.general-loading-data">Error loading data.</span> |     <span i18n="error.general-loading-data">Error loading data.</span> | ||||||
|     <br><br> |   </app-http-error> | ||||||
|     <i>{{ error.status }}: {{ error.error }}</i> |  | ||||||
|   </div> |  | ||||||
| </ng-template> | </ng-template> | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; | import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; | ||||||
| import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler, HttpResponse, HttpHeaders } from '@angular/common/http'; | import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; | ||||||
| import { Observable, of } from 'rxjs'; | import { Observable, of } from 'rxjs'; | ||||||
| import { tap } from 'rxjs/operators'; | import { catchError, tap } from 'rxjs/operators'; | ||||||
| import { TransferState, makeStateKey } from '@angular/platform-browser'; | import { TransferState, makeStateKey } from '@angular/platform-browser'; | ||||||
| import { isPlatformBrowser } from '@angular/common'; | import { isPlatformBrowser } from '@angular/common'; | ||||||
| 
 | 
 | ||||||
| @ -36,7 +36,8 @@ export class HttpCacheInterceptor implements HttpInterceptor { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return next.handle(request) |     return next.handle(request) | ||||||
|       .pipe(tap((event: HttpEvent<any>) => { |       .pipe( | ||||||
|  |         tap((event: HttpEvent<any>) => { | ||||||
|           if (!this.isBrowser && event instanceof HttpResponse) { |           if (!this.isBrowser && event instanceof HttpResponse) { | ||||||
|             let keyId = request.url.split('/').slice(3).join('/'); |             let keyId = request.url.split('/').slice(3).join('/'); | ||||||
|             const headers = {}; |             const headers = {}; | ||||||
| @ -45,6 +46,31 @@ export class HttpCacheInterceptor implements HttpInterceptor { | |||||||
|             } |             } | ||||||
|             this.transferState.set<any>(makeStateKey('/' + keyId), { response: event, headers }); |             this.transferState.set<any>(makeStateKey('/' + keyId), { response: event, headers }); | ||||||
|           } |           } | ||||||
|       })); |         }), | ||||||
|  |         catchError((e) => { | ||||||
|  |           if (e instanceof HttpErrorResponse) { | ||||||
|  |             if (e.status === 0) { | ||||||
|  |               throw new HttpErrorResponse({ | ||||||
|  |                 error: 'Unknown error', | ||||||
|  |                 headers: e.headers, | ||||||
|  |                 status: 0, | ||||||
|  |                 statusText: 'Unknown error', | ||||||
|  |                 url: e.url, | ||||||
|  |               }); | ||||||
|  |             } else { | ||||||
|  |               throw e; | ||||||
|  |             } | ||||||
|  |           } else { | ||||||
|  |             const msg = e?.['message'] || 'Unknown error'; | ||||||
|  |             throw new HttpErrorResponse({ | ||||||
|  |               error: msg, | ||||||
|  |               headers: new HttpHeaders(), | ||||||
|  |               status: 0, | ||||||
|  |               statusText: msg, | ||||||
|  |               url: '', | ||||||
|  |             }); | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       ); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,4 @@ | |||||||
|  | <div class="http-error"> | ||||||
|  |   <p><b><ng-content></ng-content></b></p> | ||||||
|  |   <i class="small">({{ error | httpErrorMsg }})</i> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,5 @@ | |||||||
|  | .http-error { | ||||||
|  |   width: 100%; | ||||||
|  |   margin: 1em auto; | ||||||
|  |   text-align: center; | ||||||
|  | } | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | import { HttpErrorResponse } from '@angular/common/http'; | ||||||
|  | import { Component, Input } from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'app-http-error', | ||||||
|  |   templateUrl: './http-error.component.html', | ||||||
|  |   styleUrls: ['./http-error.component.scss'] | ||||||
|  | }) | ||||||
|  | export class HttpErrorComponent { | ||||||
|  |   @Input() error: HttpErrorResponse | null; | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | import { HttpErrorResponse } from '@angular/common/http'; | ||||||
|  | import { Pipe, PipeTransform } from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | @Pipe({ name: 'httpErrorMsg' }) | ||||||
|  | export class HttpErrorPipe implements PipeTransform { | ||||||
|  |   transform(e: HttpErrorResponse | null): string { | ||||||
|  |     return e ? `${e.status}: ${e.statusText}` : ''; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -21,6 +21,7 @@ import { ScriptpubkeyTypePipe } from './pipes/scriptpubkey-type-pipe/scriptpubke | |||||||
| import { BytesPipe } from './pipes/bytes-pipe/bytes.pipe'; | import { BytesPipe } from './pipes/bytes-pipe/bytes.pipe'; | ||||||
| import { WuBytesPipe } from './pipes/bytes-pipe/wubytes.pipe'; | import { WuBytesPipe } from './pipes/bytes-pipe/wubytes.pipe'; | ||||||
| import { FiatCurrencyPipe } from './pipes/fiat-currency.pipe'; | import { FiatCurrencyPipe } from './pipes/fiat-currency.pipe'; | ||||||
|  | import { HttpErrorPipe } from './pipes/http-error-pipe/http-error.pipe'; | ||||||
| import { BlockchainComponent } from '../components/blockchain/blockchain.component'; | import { BlockchainComponent } from '../components/blockchain/blockchain.component'; | ||||||
| import { TimeComponent } from '../components/time/time.component'; | import { TimeComponent } from '../components/time/time.component'; | ||||||
| import { ClipboardComponent } from '../components/clipboard/clipboard.component'; | import { ClipboardComponent } from '../components/clipboard/clipboard.component'; | ||||||
| @ -104,6 +105,7 @@ import { ClockFaceComponent } from '../components/clock-face/clock-face.componen | |||||||
| import { ClockComponent } from '../components/clock/clock.component'; | import { ClockComponent } from '../components/clock/clock.component'; | ||||||
| import { CalculatorComponent } from '../components/calculator/calculator.component'; | import { CalculatorComponent } from '../components/calculator/calculator.component'; | ||||||
| import { BitcoinsatoshisPipe } from '../shared/pipes/bitcoinsatoshis.pipe'; | import { BitcoinsatoshisPipe } from '../shared/pipes/bitcoinsatoshis.pipe'; | ||||||
|  | import { HttpErrorComponent } from '../shared/components/http-error/http-error.component'; | ||||||
| 
 | 
 | ||||||
| import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-directives/weight-directives'; | import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-directives/weight-directives'; | ||||||
| 
 | 
 | ||||||
| @ -133,6 +135,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir | |||||||
|     Decimal2HexPipe, |     Decimal2HexPipe, | ||||||
|     FeeRoundingPipe, |     FeeRoundingPipe, | ||||||
|     FiatCurrencyPipe, |     FiatCurrencyPipe, | ||||||
|  |     HttpErrorPipe, | ||||||
|     ColoredPriceDirective, |     ColoredPriceDirective, | ||||||
|     BrowserOnlyDirective, |     BrowserOnlyDirective, | ||||||
|     ServerOnlyDirective, |     ServerOnlyDirective, | ||||||
| @ -208,6 +211,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir | |||||||
|     AccelerationsListComponent, |     AccelerationsListComponent, | ||||||
|     AccelerationStatsComponent, |     AccelerationStatsComponent, | ||||||
|     PendingStatsComponent, |     PendingStatsComponent, | ||||||
|  |     HttpErrorComponent, | ||||||
|   ], |   ], | ||||||
|   imports: [ |   imports: [ | ||||||
|     CommonModule, |     CommonModule, | ||||||
| @ -262,6 +266,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir | |||||||
|     VbytesPipe, |     VbytesPipe, | ||||||
|     WuBytesPipe, |     WuBytesPipe, | ||||||
|     FiatCurrencyPipe, |     FiatCurrencyPipe, | ||||||
|  |     HttpErrorPipe, | ||||||
|     CeilPipe, |     CeilPipe, | ||||||
|     ShortenStringPipe, |     ShortenStringPipe, | ||||||
|     CapAddressPipe, |     CapAddressPipe, | ||||||
| @ -327,6 +332,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir | |||||||
|     AccelerationsListComponent, |     AccelerationsListComponent, | ||||||
|     AccelerationStatsComponent, |     AccelerationStatsComponent, | ||||||
|     PendingStatsComponent, |     PendingStatsComponent, | ||||||
|  |     HttpErrorComponent, | ||||||
| 
 | 
 | ||||||
|     MempoolBlockOverviewComponent, |     MempoolBlockOverviewComponent, | ||||||
|     ClockchainComponent, |     ClockchainComponent, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user