fudgebucket27 / Lexplorer

Loopring explorer alternative
14 stars 10 forks source link

Show IPFS resolver errors when viewing NFT details #220

Closed modersohn closed 2 years ago

modersohn commented 2 years ago

Just had someone ask why their NFT wasn't showing, suspecting it was due to the size (290mb?).

0xe7a3e0d58759e2d619aa9162b6a6fbea0566139239253dd5425a035e663f986a

Upon further inspection, it's actually a minting error due to the # char in the filename. While we call NftMetadataService.GetContentTypeFromURL we actually get an error response in plain-text:

ipfs resolve -r /ipfs/QmPbU7P8DmsGAspVrc4hdPXF5Z6P3NTXZfZJ9Q8sBmax9s/AOJETFinal: no link named "AOJETFinal" under QmPbU7P8DmsGAspVrc4hdPXF5Z6P3NTXZfZJ9Q8sBmax9s
 - The root CID exists but the child file does not. - ERR_ID:00020

It would be nice if we could show this error somehow somwhere to help people figure out what's wrong.

fudgebucket27 commented 2 years ago

Possibly show an icon next to the animation url with a "!" or something and attach a tooltip to it? https://mudblazor.com/components/tooltip#simple-tooltips

modersohn commented 2 years ago

It's all getting way more complicated than anticipated and since the 2nd fix will no longer cause the first fix to show up, I'm documenting it here before the PR is ready:

  1. new NftMetadata.Error?that is shown on the details page as an alert if non-null (see below)
  2. show errors with GetContentTypeFromURL
    1. in GetContentTypeFromURL we're only getting the header, so the error message is actually not there yet
    2. But the response has a StatusNotFound, so if !response.IsSuccessfulI'll do another full request with a much shorter timeout (1s) to get the actual content
    3. Then I raise an exception with either the content, or if it's empty with StatusDescription (e.g. not found)
    4. When fetching the NFT content type in the NFT details page, exceptions are caught and added to NftMetadata.Error
    5. With the NFT mentioned above that results in what we wanted: image
  3. show errors when there's a problem with MetaData
    1. I'm still looking for examples where that actually happens
      1. most common are extra commas for the last JSON token
      2. but Newtonsoft.JSON seems to handle those gracefully by default
      3. Example: nftId 0x3a9841c0666ee92f4e96ed30ee186239134ce400521d1aca01d5ab714b42e0ec works just fine in lexplorer, but is broken on the official explorer
      4. Even our View MetaData shows a correct JSON because we regenerate it for formatting
    2. We need to be careful about that workaround there we add /metadata.json to the path
      1. Example nftId 0x4baf35a6982a81402fbe5882a47a75add97a01cc69fc418b5fc545026751f08a
      2. NftMetadataService.GetMetadata relied on GetMetadataFromResponse return null
      3. That was caused because the root CID returned a HTML page showing the content of the folder and that failed to convert to JSON.
      4. With the new code in place, the HTML page landed in NftMetaData.JSONContent and NftMetaData.Error contained the JSON version error.
      5. So for the fallback to work, we now also need to do it, if there is an NftMetaData.Errorand if NftMetaData.JSONContent actually contains "metadata.json".
  4. try to fix errors with special characters in Image/Animation URLs
    1. central place to do this is MakeIPFSLink
    2. Unfortunately Uri can't do all the work for us, as it only escapes the "data" portion
    3. so to make this work, I split the URLs at the last slash and then encode the filename portion only
    4. BUT: this breaks if this portion already is encoded! Example same nftId from point 3: 0x3a9841c0666ee92f4e96ed30ee186239134ce400521d1aca01d5ab714b42e0ec
    5. So this is only done if !Uri.IsWellFormedUriString
    6. And with that fix applied too, now the original NFT is displayed without problems: image
modersohn commented 2 years ago

Another interesting test-case - which is not affected by the PR, i.e. it still looks the same:

nftID 0x32d1a78a05f19de4b36a6baed507278828869e7a6279ca6fa95a530ed7456d3e which shows the HTML page the IPFs returns when the URL is a CID root:

image