Public API improvements (#266)

* Remove needless wrappers from API requests and responses

* Return real HTTP status codes instead of status field

* More robustly handle API errors

* Fix broken error handling in NumericResolutionPanel warmup
This commit is contained in:
Marshall Polaris 2022-05-20 14:58:14 -07:00 committed by GitHub
parent 03a13248a4
commit 540476f65a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 14 additions and 16 deletions

View File

@ -115,15 +115,13 @@ export const newEndpoint = (methods: [string], fn: Handler) =>
const allowed = methods.join(', ') const allowed = methods.join(', ')
throw new APIError(405, `This endpoint supports only ${allowed}.`) throw new APIError(405, `This endpoint supports only ${allowed}.`)
} }
const data = await fn(req, res) res.status(200).json(await fn(req, res))
data.status = 'success'
res.status(200).json({ data: data })
} catch (e) { } catch (e) {
if (e instanceof APIError) { if (e instanceof APIError) {
// Emit a 200 anyway here for now, for backwards compatibility // Emit a 200 anyway here for now, for backwards compatibility
res.status(200).json({ data: { status: 'error', message: e.msg } }) res.status(e.code).json({ message: e.msg })
} else { } else {
res.status(500).json({ data: { status: 'error', message: '???' } }) res.status(500).json({ message: 'An unknown error occurred.' })
} }
} }
}) })

View File

@ -44,7 +44,7 @@ export const createContract = newEndpoint(['POST'], async (req, _res) => {
min, min,
max, max,
manaLimitPerUser, manaLimitPerUser,
} = req.body.data || {} } = req.body || {}
if (!question || typeof question != 'string') if (!question || typeof question != 'string')
throw new APIError(400, 'Missing or invalid question field') throw new APIError(400, 'Missing or invalid question field')
@ -205,7 +205,7 @@ export const createContract = newEndpoint(['POST'], async (req, _res) => {
await anteBetDoc.set(anteBet) await anteBetDoc.set(anteBet)
} }
return { contract: contract } return contract
}) })
const getSlug = async (question: string) => { const getSlug = async (question: string) => {

View File

@ -16,7 +16,7 @@ import { Fees } from '../../common/fees'
export const placeBet = newEndpoint(['POST'], async (req, _res) => { export const placeBet = newEndpoint(['POST'], async (req, _res) => {
const [bettor, _privateUser] = await lookupUser(await parseCredentials(req)) const [bettor, _privateUser] = await lookupUser(await parseCredentials(req))
const { amount, outcome, contractId, value } = req.body.data || {} const { amount, outcome, contractId, value } = req.body || {}
if (amount <= 0 || isNaN(amount) || !isFinite(amount)) if (amount <= 0 || isNaN(amount) || !isFinite(amount))
throw new APIError(400, 'Invalid amount') throw new APIError(400, 'Invalid amount')

View File

@ -17,7 +17,7 @@ export function NumericResolutionPanel(props: {
}) { }) {
useEffect(() => { useEffect(() => {
// warm up cloud function // warm up cloud function
resolveMarket({} as any).catch() resolveMarket({} as any).catch(() => {})
}, []) }, [])
const { contract, className } = props const { contract, className } = props

View File

@ -25,14 +25,14 @@ export async function call(name: string, method: string, params: any) {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
method: method, method: method,
body: JSON.stringify({ data: params }), body: JSON.stringify(params),
}) })
return await fetch(req).then(async (resp) => { return await fetch(req).then(async (resp) => {
const json = (await resp.json()) as { [k: string]: any } const json = (await resp.json()) as { [k: string]: any }
if (json.data.status == 'error') { if (!resp.ok) {
throw new APIError(resp.status, json.data.message) throw new APIError(resp.status, json?.message)
} }
return json.data return json
}) })
} }

View File

@ -138,7 +138,7 @@ export function NewContract(props: { question: string; tag?: string }) {
max, max,
}) })
) )
await router.push(contractPath(result.contract as Contract)) await router.push(contractPath(result as Contract))
} catch (e) { } catch (e) {
console.log('error creating contract', e) console.log('error creating contract', e)
} }

View File

@ -148,14 +148,14 @@ ${TEST_VALUE}
} }
setIsSubmitting(true) setIsSubmitting(true)
for (const prediction of predictions) { for (const prediction of predictions) {
const contract = await createContract({ const contract = (await createContract({
question: prediction.question, question: prediction.question,
description: prediction.description, description: prediction.description,
initialProb: prediction.initialProb, initialProb: prediction.initialProb,
ante, ante,
closeTime, closeTime,
tags: parseWordsAsTags(tags), tags: parseWordsAsTags(tags),
}).then((r) => r.contract) })) as FullContract<DPM | CPMM, Binary>
setCreatedContracts((prev) => [...prev, contract]) setCreatedContracts((prev) => [...prev, contract])
} }