node-fetch#FetchError TypeScript Examples

The following examples show how to use node-fetch#FetchError. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: wait.ts    From bee-factory with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
function isAllowedError(e: FetchError): boolean {
  //@ts-ignore: Node 18 native fetch returns error where the underlying error is wrapped and placed in e.cause
  if (e.cause) {
    //@ts-ignore: Node 18 native fetch returns error where the underlying error is wrapped and placed in e.cause
    e = e.cause
  }

  if (e.code && ALLOWED_ERRORS.includes(e.code)) {
    return true
  }

  // Errors from Bee-js does not have the `FetchError` structure (eq. `code` property)
  // so we assert message itself.
  if (e.message.includes('socket hang up')) {
    return true
  }

  return ALLOWED_ERRORS.some(substring => e.message.includes(substring))
}
Example #2
Source File: wait.ts    From bee-factory with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
export async function waitForBlockchain(waitingIterations = 30): Promise<void> {
  for (let i = 0; i < waitingIterations; i++) {
    try {
      const request = await fetch('http://127.0.0.1:9545', {
        method: 'POST',
        body: BLOCKCHAIN_BODY_REQUEST,
        headers: { 'Content-Type': 'application/json' },
      })
      const response = (await request.json()) as { result: string }

      if (response.result === EXPECTED_CHAIN_ID) {
        return
      }
    } catch (e) {
      if (!isAllowedError(e as FetchError)) {
        throw e
      }
    }

    await sleep(AWAIT_SLEEP)
  }

  throw new TimeoutError('Waiting for blockchain container timed-out')
}
Example #3
Source File: wait.ts    From bee-factory with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
export async function waitForQueen(verifyQueenIsUp: () => Promise<boolean>, waitingIterations = 120): Promise<string> {
  const beeDebug = new BeeDebug('http://127.0.0.1:1635')

  for (let i = 0; i < waitingIterations; i++) {
    try {
      if (!(await verifyQueenIsUp())) {
        throw new Error('Queen node is not running!')
      }

      const addresses = await beeDebug.getNodeAddresses()

      if (addresses.underlay.length > 0) {
        const addr = addresses.underlay.find(addr => !addr.includes('127.0.0.1'))

        if (addr) {
          return addr
        }
      }
    } catch (e) {
      if (!isAllowedError(e as FetchError)) {
        throw e
      }
    }

    await sleep(AWAIT_SLEEP)
  }

  throw new TimeoutError('Waiting for queen container timed-out')
}
Example #4
Source File: wait.ts    From bee-factory with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
export async function waitForWorkers(
  workerCount: number,
  getStatus: () => Promise<AllStatus>,
  waitingIterations = 120,
): Promise<void> {
  const beeDebug = new BeeDebug('http://127.0.0.1:1635')

  const status = await getStatus()
  for (let i = 1; i <= workerCount; i++) {
    if (status[`worker${i}` as keyof AllStatus] !== 'running') {
      throw new Error('Some of the workers node is not running!')
    }
  }

  for (let i = 0; i < waitingIterations; i++) {
    try {
      const peers = await beeDebug.getPeers()

      if (peers.length >= workerCount) {
        return
      }
    } catch (e) {
      if (!isAllowedError(e as FetchError)) {
        throw e
      }
    }

    await sleep(AWAIT_SLEEP)
  }

  throw new TimeoutError('Waiting for worker nodes timed-out')
}
Example #5
Source File: avatarImage.ts    From ens-metadata-service with MIT License 5 votes vote down vote up
export async function avatarImage(req: Request, res: Response) {
  // #swagger.description = 'ENS avatar image'
  // #swagger.parameters['networkName'] = { schema: { $ref: '#/definitions/networkName' } }
  // #swagger.parameters['name'] = { description: 'ENS name', schema: { $ref: '#/definitions/ensName' } }
  const { name, networkName } = req.params;
  try {
    const { provider } = getNetwork(networkName);
    const [buffer, mimeType] = await getAvatarImage(provider, name);
    if (buffer) {
      /* #swagger.responses[200] = { 
           description: 'Image file'
      } */
      res.writeHead(200, {
        'Content-Type': mimeType,
        'Content-Length': buffer.length,
      });
      res.end(buffer);
    }
    /* #swagger.responses[404] = { 
           description: 'No results found' 
    } */
    res.status(404).json({
      message: 'No results found.',
    });
  } catch (error: any) {
    const errCode = (error?.code && Number(error.code)) || 500;
    if (
      error instanceof FetchError ||
      error instanceof NFTURIParsingError ||
      error instanceof ResolverNotFound ||
      error instanceof RetrieveURIFailed ||
      error instanceof TextRecordNotFound ||
      error instanceof UnsupportedNamespace
    ) {
      res.status(errCode).json({
        message: error.message,
      });
      return;
    }
    /* #swagger.responses[501] = { 
          description: 'Unsupported network' 
    } */
    if (error instanceof UnsupportedNetwork) {
      res.status(501).json({
        message: error.message,
      });
    }
  }
}
Example #6
Source File: avatarMetadata.ts    From ens-metadata-service with MIT License 5 votes vote down vote up
export async function avatarMetadata(req: Request, res: Response) {
  // #swagger.description = 'ENS avatar metadata'
  // #swagger.parameters['networkName'] = { schema: { $ref: '#/definitions/networkName' } }
  // #swagger.parameters['name'] = { description: 'ENS name', schema: { $ref: '#/definitions/ensName' } }
  const { name, networkName } = req.params;
  try {
    const { provider } = getNetwork(networkName);
    const meta = await getAvatarMeta(provider, name, networkName);
    if (meta) {
      /* #swagger.responses[200] = { 
             description: 'Metadata object',
             schema: { $ref: '#/definitions/AvatarMetadata' }
      } */
      res.status(200).json(meta);
    } else {
      /* #swagger.responses[404] = { 
             description: 'No results found' 
      } */
      res.status(404).json({
        message: 'No results found.',
      });
    }
  } catch (error: any) {
    const errCode = (error?.code && Number(error.code)) || 500;
    if (
      error instanceof FetchError ||
      error instanceof NFTURIParsingError ||
      error instanceof ResolverNotFound ||
      error instanceof RetrieveURIFailed ||
      error instanceof TextRecordNotFound ||
      error instanceof UnsupportedNamespace
    ) {
      res.status(errCode).json({
        message: error.message,
      });
      return;
    }
    /* #swagger.responses[501] = { 
          description: 'Unsupported network' 
    } */
    if (error instanceof UnsupportedNetwork) {
      res.status(501).json({
        message: error.message,
      });
    }
  }
}
Example #7
Source File: ensImage.ts    From ens-metadata-service with MIT License 5 votes vote down vote up
/* istanbul ignore next */
export async function ensImage(req: Request, res: Response) {
  // #swagger.description = 'ENS NFT image'
  // #swagger.parameters['networkName'] = { schema: { $ref: '#/definitions/networkName' } }
  // #swagger.parameters['{}'] = { name: 'contractAddress', description: 'Contract address which stores the NFT indicated by the tokenId', type: 'string', schema: { $ref: '#/definitions/contractAddress' } }
  // #swagger.parameters['tokenId'] = { type: 'string', description: 'Labelhash(v1) /Namehash(v2) of your ENS name.\n\nMore: https://docs.ens.domains/contract-api-reference/name-processing#hashing-names', schema: { $ref: '#/definitions/tokenId' } }
  const { contractAddress, networkName, tokenId } = req.params;
  const _tokenId = getLabelhash(tokenId);

  try {
    const { provider, SUBGRAPH_URL } = getNetwork(networkName);
    const version = await checkContract(provider, contractAddress, _tokenId);
    const result = await getDomain(
      provider,
      networkName,
      SUBGRAPH_URL,
      contractAddress,
      _tokenId,
      version
    );
    if (result.image_url) {
      const base64 = result.image_url.replace('data:image/svg+xml;base64,', '');
      const buffer = Buffer.from(base64, 'base64');
      res.writeHead(200, {
        'Content-Type': 'image/svg+xml',
        'Content-Length': buffer.length,
      });
      res.end(buffer);
    } else {
      throw Error('Image URL is missing.');
    }
    /* #swagger.responses[200] = { 
        description: 'Image file'
    } */
  } catch (error) {
    if (error instanceof FetchError || error instanceof ContractMismatchError) {
      /* #swagger.responses[404] = { 
           description: 'No results found' 
      } */
      res.status(404).json({
        message: error.message,
      });
      return;
    }
    /* #swagger.responses[501] = { 
           description: 'Unsupported network' 
    } */
    if (error instanceof UnsupportedNetwork) {
      res.status(501).json({
        message: error.message,
      });
    }
    /* #swagger.responses[404] = { 
           description: 'No results found' 
    } */
    res.status(404).json({
      message: 'No results found.',
    });
  }
}
Example #8
Source File: tokens-contract-handler.ts    From stacks-blockchain-api with GNU General Public License v3.0 5 votes vote down vote up
/**
   * Fetch metadata from uri
   */
  private async getMetadataFromUri<Type>(token_uri: string): Promise<Type> {
    // Support JSON embedded in a Data URL
    if (new URL(token_uri).protocol === 'data:') {
      const dataUrl = parseDataUrl(token_uri);
      if (!dataUrl) {
        throw new Error(`Data URL could not be parsed: ${token_uri}`);
      }
      let content: string;
      // If media type is omitted it should default to percent-encoded `text/plain;charset=US-ASCII`
      // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs#syntax
      // If media type is specified but without base64 then encoding is ambiguous, so check for
      // percent-encoding or assume a literal string compatible with utf8. Because we're expecting
      // a JSON object we can reliable check for a leading `%` char, otherwise assume unescaped JSON.
      if (dataUrl.base64) {
        content = Buffer.from(dataUrl.data, 'base64').toString('utf8');
      } else if (dataUrl.data.startsWith('%')) {
        content = querystring.unescape(dataUrl.data);
      } else {
        content = dataUrl.data;
      }
      try {
        return JSON.parse(content) as Type;
      } catch (error) {
        throw new Error(`Data URL could not be parsed as JSON: ${token_uri}`);
      }
    }
    const httpUrl = this.getFetchableUrl(token_uri);

    let fetchImmediateRetryCount = 0;
    let result: Type | undefined;
    // We'll try to fetch metadata and give it `METADATA_MAX_IMMEDIATE_RETRY_COUNT` attempts
    // for the external service to return a reasonable response, otherwise we'll consider the
    // metadata as dead.
    do {
      try {
        result = await performFetch(httpUrl.toString(), {
          timeoutMs: getTokenMetadataFetchTimeoutMs(),
          maxResponseBytes: METADATA_MAX_PAYLOAD_BYTE_SIZE,
        });
        break;
      } catch (error) {
        fetchImmediateRetryCount++;
        if (
          (error instanceof FetchError && error.type === 'max-size') ||
          fetchImmediateRetryCount >= METADATA_MAX_IMMEDIATE_RETRY_COUNT
        ) {
          throw error;
        }
      }
    } while (fetchImmediateRetryCount < METADATA_MAX_IMMEDIATE_RETRY_COUNT);
    if (result) {
      return result;
    }
    throw new Error(`Unable to fetch metadata from ${token_uri}`);
  }
Example #9
Source File: ensMetadata.ts    From ens-metadata-service with MIT License 4 votes vote down vote up
export async function ensMetadata(req: Request, res: Response) {
  // #swagger.description = 'ENS NFT metadata'
  // #swagger.parameters['networkName'] = { schema: { $ref: '#/definitions/networkName' } }
  // #swagger.parameters['{}'] = { name: 'contractAddress', description: 'Contract address which stores the NFT indicated by the tokenId', schema: { $ref: '#/definitions/contractAddress' } }
  // #swagger.parameters['tokenId'] = { type: 'string', description: 'Labelhash(v1) /Namehash(v2) of your ENS name.\n\nMore: https://docs.ens.domains/contract-api-reference/name-processing#hashing-names', schema: { $ref: '#/definitions/tokenId' } }
  const { contractAddress, networkName, tokenId } = req.params;
  const _tokenId = getLabelhash(tokenId);

  const { provider, SUBGRAPH_URL } = getNetwork(networkName);
  let version;
  try {
    version = await checkContract(provider, contractAddress, _tokenId);
    const result = await getDomain(
      provider,
      networkName,
      SUBGRAPH_URL,
      contractAddress,
      _tokenId,
      version,
      false
    );
    /* #swagger.responses[200] = { 
             description: 'Metadata object',
             schema: { $ref: '#/definitions/ENSMetadata' }
    } */
    res.json(result);
  } catch (error: any) {
    let errCode = (error?.code && Number(error.code)) || 500;
    /* #swagger.responses[500] = { 
             description: 'Internal Server Error'
    } */
    if (error instanceof FetchError || error instanceof ContractMismatchError) {
      if (errCode !== 404) {
        res.status(errCode).json({
          message: error.message,
        });
        return;
      }
    }
    /* #swagger.responses[501] = { 
           description: 'Unsupported network' 
    } */
    if (error instanceof UnsupportedNetwork) {
      res.status(501).json({
        message: error.message,
      });
      return;
    }

    try {
      const registry = new Contract(
        ADDRESS_ETH_REGISTRY,
        ETH_REGISTRY_ABI,
        provider
      );

      const _namehash = constructEthNameHash(_tokenId, version as Version);
      const isRecordExist = await registry.recordExists(_namehash);
      assert(isRecordExist, 'ENS name does not exist');
    } catch (error) {
      /* #swagger.responses[404] = {
             description: 'No results found'
      } */
      res.status(404).json({
        message: 'No results found.',
      });
      return;
    }

    // When entry is not available on subgraph yet,
    // return unknown name metadata with 200 status code
    const { url, ...unknownMetadata } = new Metadata({
      name: 'unknown.name',
      description: 'Unknown ENS name',
      created_date: 1580346653000,
      tokenId: '',
      version: Version.v1,
    });
    res.status(200).json({
      message: unknownMetadata,
    });
  }
}