From 41413fea9dae778d072e285c36e6363934422d2c Mon Sep 17 00:00:00 2001
From: Giovanni Abbatepaolo <30571828+bbtgnn@users.noreply.github.com>
Date: Tue, 30 Jan 2024 13:58:15 +0100
Subject: [PATCH] feat: Add DID detail error (#70)
* chore: autoformat
* feat: display fetch error
* feat: add statusText property
---
explorer/app/details/[did]/page.tsx | 40 ++++++++++++++++++++++++-----
explorer/lib/fetcher.ts | 30 +++++++++++++++++-----
explorer/lib/resolver.ts | 40 +++++++++++++++++------------
3 files changed, 80 insertions(+), 30 deletions(-)
diff --git a/explorer/app/details/[did]/page.tsx b/explorer/app/details/[did]/page.tsx
index b2c9b7f..0e67ff8 100644
--- a/explorer/app/details/[did]/page.tsx
+++ b/explorer/app/details/[did]/page.tsx
@@ -7,11 +7,22 @@ import CopyButton from "@/ui/CopyButton";
import IconButton from "@/ui/IconButton";
import ArrowLeft from "@/ui/icons/ArrowLeft";
import Link from "next/link";
+import { DIDResolutionResult } from "did-resolver";
+import { FetchError } from "lib/fetcher";
//
export default async function Page({ params }: { params: { did: string } }) {
- const document = await resolve(decodeURIComponent(params.did));
+ let document: DIDResolutionResult | undefined = undefined;
+ let error: FetchError | undefined = undefined;
+
+ try {
+ document = await resolve(decodeURIComponent(params.did));
+ } catch (e) {
+ if (e instanceof FetchError) error = e;
+ else
+ error = new FetchError(500, "Something went wrong :O", "Unknown error");
+ }
return (
<>
@@ -30,13 +41,28 @@ export default async function Page({ params }: { params: { did: string } }) {
-
-
-
+ {document && (
+ <>
+
+
+
+
+
+
+
+ >
+ )}
-
-
-
+ {error && (
+
+
+
+ Error | {error.status} - {error.statusText}
+
+
{error.message}
+
+
+ )}
>
);
}
diff --git a/explorer/lib/fetcher.ts b/explorer/lib/fetcher.ts
index 56084c5..54f5312 100644
--- a/explorer/lib/fetcher.ts
+++ b/explorer/lib/fetcher.ts
@@ -1,9 +1,27 @@
-const base_url = 'https://did.dyne.org';
+const base_url = "https://did.dyne.org";
export const getData = async (endpoint: string) => {
- const res = await fetch(`${base_url}/${endpoint}`);
- if (!res.ok) {
- throw new Error(`Failed to fetch data from ${endpoint}`);
- }
- return res.json();
+ const res = await fetch(`${base_url}/${endpoint}`);
+ if (!res.ok) {
+ throw new FetchError(
+ res.status,
+ `Failed to fetch data from ${endpoint}`,
+ res.statusText
+ );
+ }
+ return res.json();
+};
+
+export class FetchError extends Error {
+ status: number;
+ message: string;
+ statusText: string;
+
+ constructor(status: number, message: string, statusText: string) {
+ super(message);
+ this.name = "FetchError";
+ this.status = status;
+ this.message = message;
+ this.statusText = statusText;
+ }
}
diff --git a/explorer/lib/resolver.ts b/explorer/lib/resolver.ts
index a8a4c5c..fbccff4 100644
--- a/explorer/lib/resolver.ts
+++ b/explorer/lib/resolver.ts
@@ -1,22 +1,28 @@
-import { DIDResolutionOptions, DIDResolutionResult, ParsedDID, Resolvable, Resolver } from "did-resolver";
+import {
+ DIDResolutionOptions,
+ DIDResolutionResult,
+ ParsedDID,
+ Resolvable,
+ Resolver,
+} from "did-resolver";
import { getData } from "./fetcher";
const resolver = new Resolver({
- dyne: async function resolve(
- did: string,
- parsed: ParsedDID,
- didResolver: Resolvable,
- options: DIDResolutionOptions
- ): Promise {
- // {method: 'mymethod', id: 'abcdefg', did: 'did:mymethod:abcdefg/some/path#fragment=123', path: '/some/path', fragment: 'fragment=123'}
- const didDoc = await getData(`dids/${did}`);
- // If you need to lookup another did as part of resolving this did document, the primary DIDResolver object is passed in as well
- // const parentDID = await didResolver.resolve(...)
- // Return the DIDResolutionResult object
- return didDoc
- }
-})
+ dyne: async function resolve(
+ did: string,
+ parsed: ParsedDID,
+ didResolver: Resolvable,
+ options: DIDResolutionOptions
+ ): Promise {
+ // {method: 'mymethod', id: 'abcdefg', did: 'did:mymethod:abcdefg/some/path#fragment=123', path: '/some/path', fragment: 'fragment=123'}
+ const didDoc = await getData(`dids/${did}`);
+ // If you need to lookup another did as part of resolving this did document, the primary DIDResolver object is passed in as well
+ // const parentDID = await didResolver.resolve(...)
+ // Return the DIDResolutionResult object
+ return didDoc;
+ },
+});
export const resolve = async (didUrl: string): Promise => {
- return await resolver.resolve(didUrl)
-}
+ return await resolver.resolve(didUrl);
+};