From 484e032775828e06d30ed9d9304b97ce60741210 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Thu, 21 Mar 2024 07:57:13 +0000 Subject: [PATCH 1/2] Reusable component & pipe for http error rendering --- .../bisq-address/bisq-address.component.html | 8 +++----- .../components/address/address.component.html | 20 +++++++++++-------- .../components/address/address.component.ts | 16 +++++++++++++-- .../app/components/asset/asset.component.html | 7 ++----- .../components/assets/assets.component.html | 8 +++----- .../app/components/block/block.component.html | 18 +++++++---------- .../transaction/transaction.component.html | 6 +++--- .../channel/channel-preview.component.html | 6 ++---- .../http-error/http-error.component.html | 4 ++++ .../http-error/http-error.component.scss | 5 +++++ .../http-error/http-error.component.ts | 11 ++++++++++ .../pipes/http-error-pipe/http-error.pipe.ts | 9 +++++++++ frontend/src/app/shared/shared.module.ts | 6 ++++++ 13 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 frontend/src/app/shared/components/http-error/http-error.component.html create mode 100644 frontend/src/app/shared/components/http-error/http-error.component.scss create mode 100644 frontend/src/app/shared/components/http-error/http-error.component.ts create mode 100644 frontend/src/app/shared/pipes/http-error-pipe/http-error.pipe.ts diff --git a/frontend/src/app/bisq/bisq-address/bisq-address.component.html b/frontend/src/app/bisq/bisq-address/bisq-address.component.html index c2cbbb76a..6b0d27c2c 100644 --- a/frontend/src/app/bisq/bisq-address/bisq-address.component.html +++ b/frontend/src/app/bisq/bisq-address/bisq-address.component.html @@ -98,11 +98,9 @@ -
- Error loading address data. -
- {{ error.error }} -
+ + Error loading address data. +
diff --git a/frontend/src/app/components/address/address.component.html b/frontend/src/app/components/address/address.component.html index 41a9c3061..e4c49d4c5 100644 --- a/frontend/src/app/components/address/address.component.html +++ b/frontend/src/app/components/address/address.component.html @@ -135,11 +135,10 @@
-
- Error loading address data. -
- ({{ error.error }}) - + +
+ Error loading address data. +
There many transactions on this address, more than your backend can handle. See more on setting up a stronger backend.

@@ -150,9 +149,14 @@
http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/address/{{ addressString }}

- ({{ error.error }}) - -
+ ({{ error | httpErrorMsg }}) +
+
+ + + Error loading address data. + + diff --git a/frontend/src/app/components/address/address.component.ts b/frontend/src/app/components/address/address.component.ts index 52a66c2be..8b325e653 100644 --- a/frontend/src/app/components/address/address.component.ts +++ b/frontend/src/app/components/address/address.component.ts @@ -140,10 +140,22 @@ export class AddressComponent implements OnInit, OnDestroy { if (!fetchTxs.length) { 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) => { this.tempTransactions[this.timeTxIndexes[index]].firstSeen = time; }); diff --git a/frontend/src/app/components/asset/asset.component.html b/frontend/src/app/components/asset/asset.component.html index 862055f22..a7f4d3118 100644 --- a/frontend/src/app/components/asset/asset.component.html +++ b/frontend/src/app/components/asset/asset.component.html @@ -146,13 +146,10 @@ -
+ Error loading asset data. -
- {{ error.error }} -
+
-
diff --git a/frontend/src/app/components/assets/assets.component.html b/frontend/src/app/components/assets/assets.component.html index 51a2f7696..c279af2ab 100644 --- a/frontend/src/app/components/assets/assets.component.html +++ b/frontend/src/app/components/assets/assets.component.html @@ -46,9 +46,7 @@ -
- Error loading assets data. -
- {{ error.error }} -
+ + Error loading assets data. +
diff --git a/frontend/src/app/components/block/block.component.html b/frontend/src/app/components/block/block.component.html index f3cf45f0f..0c0655c01 100644 --- a/frontend/src/app/components/block/block.component.html +++ b/frontend/src/app/components/block/block.component.html @@ -338,14 +338,12 @@ -
-
+
+ Error loading data. -

- {{ transactionsError.status }}: {{ transactionsError.error }} -
-
-
+ +
+
@@ -378,11 +376,9 @@
-
+ Error loading data. -

- {{ error.status }}: {{ error.error }} -
+
diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html index 1e204f6be..0110c5456 100644 --- a/frontend/src/app/components/transaction/transaction.component.html +++ b/frontend/src/app/components/transaction/transaction.component.html @@ -517,9 +517,9 @@ -
-

{{ error.error }}

-
+ + Error loading transaction data. +
diff --git a/frontend/src/app/lightning/channel/channel-preview.component.html b/frontend/src/app/lightning/channel/channel-preview.component.html index e59361e42..108fe2e95 100644 --- a/frontend/src/app/lightning/channel/channel-preview.component.html +++ b/frontend/src/app/lightning/channel/channel-preview.component.html @@ -66,9 +66,7 @@ -
+ Error loading data. -

- {{ error.status }}: {{ error.error }} -
+
diff --git a/frontend/src/app/shared/components/http-error/http-error.component.html b/frontend/src/app/shared/components/http-error/http-error.component.html new file mode 100644 index 000000000..036a281da --- /dev/null +++ b/frontend/src/app/shared/components/http-error/http-error.component.html @@ -0,0 +1,4 @@ +
+

+ ({{ error | httpErrorMsg }}) +
\ No newline at end of file diff --git a/frontend/src/app/shared/components/http-error/http-error.component.scss b/frontend/src/app/shared/components/http-error/http-error.component.scss new file mode 100644 index 000000000..fe7c4de5a --- /dev/null +++ b/frontend/src/app/shared/components/http-error/http-error.component.scss @@ -0,0 +1,5 @@ +.http-error { + width: 100%; + margin: 1em auto; + text-align: center; +} \ No newline at end of file diff --git a/frontend/src/app/shared/components/http-error/http-error.component.ts b/frontend/src/app/shared/components/http-error/http-error.component.ts new file mode 100644 index 000000000..0e4c93e81 --- /dev/null +++ b/frontend/src/app/shared/components/http-error/http-error.component.ts @@ -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; +} diff --git a/frontend/src/app/shared/pipes/http-error-pipe/http-error.pipe.ts b/frontend/src/app/shared/pipes/http-error-pipe/http-error.pipe.ts new file mode 100644 index 000000000..3cbb16df6 --- /dev/null +++ b/frontend/src/app/shared/pipes/http-error-pipe/http-error.pipe.ts @@ -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}` : ''; + } +} diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index cdf08635c..5e58ef080 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -21,6 +21,7 @@ import { ScriptpubkeyTypePipe } from './pipes/scriptpubkey-type-pipe/scriptpubke import { BytesPipe } from './pipes/bytes-pipe/bytes.pipe'; import { WuBytesPipe } from './pipes/bytes-pipe/wubytes.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 { TimeComponent } from '../components/time/time.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 { CalculatorComponent } from '../components/calculator/calculator.component'; 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'; @@ -133,6 +135,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir Decimal2HexPipe, FeeRoundingPipe, FiatCurrencyPipe, + HttpErrorPipe, ColoredPriceDirective, BrowserOnlyDirective, ServerOnlyDirective, @@ -208,6 +211,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir AccelerationsListComponent, AccelerationStatsComponent, PendingStatsComponent, + HttpErrorComponent, ], imports: [ CommonModule, @@ -262,6 +266,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir VbytesPipe, WuBytesPipe, FiatCurrencyPipe, + HttpErrorPipe, CeilPipe, ShortenStringPipe, CapAddressPipe, @@ -327,6 +332,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir AccelerationsListComponent, AccelerationStatsComponent, PendingStatsComponent, + HttpErrorComponent, MempoolBlockOverviewComponent, ClockchainComponent, From 13fb75fec3159c94272ffe3f36f3e78e0c232cf5 Mon Sep 17 00:00:00 2001 From: Mononaut Date: Thu, 21 Mar 2024 08:00:41 +0000 Subject: [PATCH 2/2] Extend http interceptor to normalize errors --- .../app/services/http-cache.interceptor.ts | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/frontend/src/app/services/http-cache.interceptor.ts b/frontend/src/app/services/http-cache.interceptor.ts index c7624887a..c0f1646ad 100644 --- a/frontend/src/app/services/http-cache.interceptor.ts +++ b/frontend/src/app/services/http-cache.interceptor.ts @@ -1,7 +1,7 @@ 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 { tap } from 'rxjs/operators'; +import { catchError, tap } from 'rxjs/operators'; import { TransferState, makeStateKey } from '@angular/platform-browser'; import { isPlatformBrowser } from '@angular/common'; @@ -36,15 +36,41 @@ export class HttpCacheInterceptor implements HttpInterceptor { } return next.handle(request) - .pipe(tap((event: HttpEvent) => { - if (!this.isBrowser && event instanceof HttpResponse) { - let keyId = request.url.split('/').slice(3).join('/'); - const headers = {}; - for (const k of event.headers.keys()) { - headers[k] = event.headers.getAll(k); + .pipe( + tap((event: HttpEvent) => { + if (!this.isBrowser && event instanceof HttpResponse) { + let keyId = request.url.split('/').slice(3).join('/'); + const headers = {}; + for (const k of event.headers.keys()) { + headers[k] = event.headers.getAll(k); + } + this.transferState.set(makeStateKey('/' + keyId), { response: event, headers }); } - this.transferState.set(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: '', + }); + } + }) + ); } }