alephjs / aleph.js

The Full-stack Framework in Deno.
https://aleph.deno.dev/
MIT License
5.26k stars 167 forks source link

Getting "http: response headers already sent" on Deno 1.16.1 #428

Open talentlessguy opened 2 years ago

talentlessguy commented 2 years ago

Example code: (api/wallet.ts)

import { balance } from 'https://deno.land/x/balance_crypto@0.2.15/deno/mod.ts'
import { LRU } from 'https://deno.land/x/lru@1.0.2/mod.ts'
import type { APIHandler } from 'aleph/types.d.ts'

type ThenArg<T> = T extends PromiseLike<infer U> ? U : T

type PromiseValue<F extends (...args: any[]) => any> = ThenArg<ReturnType<F>> // => number

const toOne = (x: any | any[]) => (x ? (Array.isArray(x) ? x[0] : x) : false)

type WalletData = {
  balance: number
  address: string
  token: string
  qrImg: string
  logoURI: string
}

const cache = new LRU<PromiseValue<typeof balance>>(5)

const handler: APIHandler = async ({ request, response: res }) => {
  const params = new URL(request.url).searchParams

  const address = params.get('address')
  let coin = params.get('coin')

  if (!coin || !address) {
    res.status = 400

    if (!coin) res.body = 'Missing token symbol'
    if (!address) res.body = 'Missing address'
    return
  }

  coin = coin.toUpperCase()

  let balanceValue = 0

  let result = cache.get(`${address}-${coin}`)

  if (!result) {
    result = await balance(address, coin, {
      apiKeys: {
        etherscan: Deno.env.get('ETHERSCAN_KEY'),
        blockcypher: Deno.env.get('BLOCKCYPHER_KEY')
      },
      verbose: true
    })
    cache.set(`${address}-${coin}`, result)
  }

  const digits = parseInt(toOne(params.get('digits')))

  if (result?.balance) balanceValue = parseFloat(result!.balance.toFixed(digits < 10 ? digits : 3))

  res.body = JSON.stringify({
    token: coin,
    qrImg: `https://chart.googleapis.com/chart?chs=250x250&cht=qr&chl=${address}&choe=UTF-8`,
    logoURI: `https://cdn.jsdelivr.net/gh/atomiclabs/cryptocurrency-icons@v0.18.0/svg/color/${coin.toLowerCase()}.svg`,
    ...result,
    balance: balanceValue,
    address
  } as WalletData)
}

export default handler

Example request:

http://localhost:8080/api/wallet?coin=usdc&address=0xD3B282e9880cDcB1142830731cD83f7ac0e1043f

Environment

hazae41 commented 2 years ago

Hello, thank for submitting this issue.

Can you try to isolate the bug by finding what works in your code and what does not?