Skip to content

Commit

Permalink
Handle DP request timeouts (#21)
Browse files Browse the repository at this point in the history
* Handle DP request timeouts

* Fix lint errors
  • Loading branch information
piazzatron committed Dec 15, 2020
1 parent 464ed27 commit 55df6ce
Show file tree
Hide file tree
Showing 13 changed files with 144 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ const BarChart: React.FC<BarChartProps> = ({
</div>
<div className={styles.chart}>
{error ? (
<Error text="Incomplete Data" />
<Error />
) : data && labels ? (
<>
<div className={styles.columns}>
Expand Down
4 changes: 3 additions & 1 deletion packages/protocol-dashboard/src/components/Error/Error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { ReactComponent as IconUhOh } from 'assets/img/uhOh.svg'

import styles from './Error.module.css'

const Error = ({ text }: { text: string }) => {
const DEFAULT_ERROR_TEXT = 'Incomplete Data'

const Error = ({ text = DEFAULT_ERROR_TEXT }: { text?: string }) => {
return (
<div className={styles.error}>
<Tooltip text={text}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ const LineChart: React.FC<LineChartProps> = ({
</div>
<div className={styles.chart}>
{error ? (
<Error text="Incomplete Data" />
<Error />
) : data && labels ? (
<Line
data={getData(data, labels, showLeadingDay)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const RadarChart: React.FC<RadarChartProps> = ({
</div>
<div className={styles.chart}>
{error ? (
<Error text="Incomplete Data" />
<Error />
) : data && labels ? (
<Radar data={getData(data, labels)} options={getOptions()} />
) : (
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol-dashboard/src/components/Stat/Stat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Stat: React.FC<StatProps> = ({ stat, label, error }) => {
<Paper className={styles.container}>
{error ? (
<div className={styles.stat}>
<Error text="Incomplete Data" />
<Error />
</div>
) : stat !== null ? (
<div className={styles.stat}>{stat}</div>
Expand Down
58 changes: 30 additions & 28 deletions packages/protocol-dashboard/src/components/TopAlbums/TopAlbums.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Error from 'components/Error'
import Loading from 'components/Loading'
import Paper from 'components/Paper'
import React, { useCallback } from 'react'
import { useTopAlbums } from 'store/cache/music/hooks'
import { MusicError } from 'store/cache/music/slice'
import { formatShortNumber } from 'utils/format'

import styles from './TopAlbums.module.css'
Expand All @@ -19,37 +21,37 @@ const TopAlbums: React.FC<TopAlbumsProps> = () => {
const goToUrl = useCallback((url: string) => {
window.open(url, '_blank')
}, [])

const renderTopAlbums = () => {
if (topAlbums === MusicError.ERROR) return <Error />
return !!topAlbums ? (
topAlbums.map((p, i) => (
<div key={i} className={styles.album} onClick={() => goToUrl(p.url)}>
<div
className={styles.artwork}
onClick={() => goToUrl(p.url)}
style={{
backgroundImage: `url(${p.artwork})`
}}
/>
<div className={styles.text}>
<div className={styles.albumTitle}>{p.title}</div>
<div className={styles.handle}>{p.handle}</div>
</div>
<div className={styles.plays}>
{`${formatShortNumber(p.plays)} Plays`}
</div>
</div>
))
) : (
<Loading className={styles.loading} />
)
}

return (
<Paper className={styles.container}>
<div className={styles.title}>{messages.title}</div>
<div className={styles.albums}>
{!!topAlbums ? (
topAlbums.map((p, i) => (
<div
key={i}
className={styles.album}
onClick={() => goToUrl(p.url)}
>
<div
className={styles.artwork}
onClick={() => goToUrl(p.url)}
style={{
backgroundImage: `url(${p.artwork})`
}}
/>
<div className={styles.text}>
<div className={styles.albumTitle}>{p.title}</div>
<div className={styles.handle}>{p.handle}</div>
</div>
<div className={styles.plays}>
{`${formatShortNumber(p.plays)} Plays`}
</div>
</div>
))
) : (
<Loading className={styles.loading} />
)}
</div>
<div className={styles.albums}>{renderTopAlbums()}</div>
</Paper>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Error from 'components/Error'
import Loading from 'components/Loading'
import Paper from 'components/Paper'
import React, { useCallback } from 'react'
import { useTopPlaylists } from 'store/cache/music/hooks'
import { MusicError } from 'store/cache/music/slice'
import { formatShortNumber } from 'utils/format'

import styles from './TopPlaylists.module.css'
Expand All @@ -19,36 +21,35 @@ const TopPlaylists: React.FC<TopPlaylistsProps> = () => {
const goToUrl = useCallback((url: string) => {
window.open(url, '_blank')
}, [])

const renderTopPlaylists = () => {
if (topPlaylists === MusicError.ERROR) return <Error />
return !!topPlaylists ? (
topPlaylists!.map((p, i) => (
<div key={i} className={styles.playlist} onClick={() => goToUrl(p.url)}>
<div
className={styles.artwork}
style={{
backgroundImage: `url(${p.artwork})`
}}
/>
<div className={styles.text}>
<div className={styles.playlistTitle}>{p.title}</div>
<div className={styles.handle}>{p.handle}</div>
</div>
<div className={styles.plays}>
{`${formatShortNumber(p.plays)} Plays`}
</div>
</div>
))
) : (
<Loading className={styles.loading} />
)
}
return (
<Paper className={styles.container}>
<div className={styles.title}>{messages.title}</div>
<div className={styles.playlists}>
{!!topPlaylists ? (
topPlaylists!.map((p, i) => (
<div
key={i}
className={styles.playlist}
onClick={() => goToUrl(p.url)}
>
<div
className={styles.artwork}
style={{
backgroundImage: `url(${p.artwork})`
}}
/>
<div className={styles.text}>
<div className={styles.playlistTitle}>{p.title}</div>
<div className={styles.handle}>{p.handle}</div>
</div>
<div className={styles.plays}>
{`${formatShortNumber(p.plays)} Plays`}
</div>
</div>
))
) : (
<Loading className={styles.loading} />
)}
</div>
<div className={styles.playlists}>{renderTopPlaylists()}</div>
</Paper>
)
}
Expand Down
51 changes: 28 additions & 23 deletions packages/protocol-dashboard/src/components/TopTracks/TopTracks.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Error from 'components/Error'
import Loading from 'components/Loading'
import Paper from 'components/Paper'
import React, { useCallback } from 'react'
import { useTopTracks } from 'store/cache/music/hooks'
import { MusicError } from 'store/cache/music/slice'
import { createStyles } from 'utils/mobile'

import desktopStyles from './TopTracks.module.css'
Expand All @@ -22,32 +24,35 @@ const TopTracks: React.FC<TopTracksProps> = () => {
const goToUrl = useCallback((url: string) => {
window.open(url, '_blank')
}, [])

const renderTopTracks = () => {
if (topTracks === MusicError.ERROR) return <Error />
return !!topTracks ? (
topTracks.map((t, i) => (
<div key={i} className={styles.track}>
<div
className={styles.artwork}
onClick={() => goToUrl(t.url)}
style={{
backgroundImage: `url(${t.artwork})`
}}
/>
<div className={styles.trackTitle} onClick={() => goToUrl(t.url)}>
{t.title}
</div>
<div className={styles.handle} onClick={() => goToUrl(t.userUrl)}>
{t.handle}
</div>
</div>
))
) : (
<Loading className={styles.loading} />
)
}
return (
<Paper className={styles.container}>
<div className={styles.title}>{messages.title}</div>
<div className={styles.tracks}>
{!!topTracks ? (
topTracks.map((t, i) => (
<div key={i} className={styles.track}>
<div
className={styles.artwork}
onClick={() => goToUrl(t.url)}
style={{
backgroundImage: `url(${t.artwork})`
}}
/>
<div className={styles.trackTitle} onClick={() => goToUrl(t.url)}>
{t.title}
</div>
<div className={styles.handle} onClick={() => goToUrl(t.userUrl)}>
{t.handle}
</div>
</div>
))
) : (
<Loading className={styles.loading} />
)}
</div>
<div className={styles.tracks}>{renderTopTracks()}</div>
</Paper>
)
}
Expand Down
7 changes: 4 additions & 3 deletions packages/protocol-dashboard/src/services/Audius/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Utils } from '@audius/libs'
import { formatNumber, formatAudString } from 'utils/format'
import AudiusClient from './AudiusClient'
import { Permission, BigNumber } from 'types'
import { fetchWithTimeout } from 'utils/fetch'

// Helpers
export async function hasPermissions(
Expand Down Expand Up @@ -113,9 +114,9 @@ export function getWei(amount: BigNumber) {

export async function getNodeVersion(endpoint: string): Promise<string> {
try {
const version = await fetch(`${endpoint}/health_check`)
.then(res => res.json())
.then(r => r.data.version)
const version = await fetchWithTimeout(`${endpoint}/health_check`).then(
r => r.data.version
)
return version
} catch (e) {
console.error(e)
Expand Down
28 changes: 7 additions & 21 deletions packages/protocol-dashboard/src/store/cache/analytics/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { useAverageBlockTime, useEthBlockNumber } from '../protocol/hooks'
import { weiAudToAud } from 'utils/numeric'
import { ELECTRONIC_SUB_GENRES } from './genres'
import { performWithFallback } from 'utils/performWithFallback'

import { fetchWithTimeout } from '../../../utils/fetch'
dayjs.extend(duration)

const MONTH_IN_MS = dayjs.duration({ months: 1 }).asMilliseconds()
Expand Down Expand Up @@ -187,7 +187,7 @@ async function fetchTimeSeries(
try {
const bucket_size = BUCKET_GRANULARITY_MAP[bucket]
const url = `${node.endpoint}/v1/metrics/${route}?bucket_size=${bucket_size}&start_time=${startTime}`
const res = await (await fetch(url)).json()
const res = await fetchWithTimeout(url)
return res.data
} catch (e) {
console.error(e)
Expand Down Expand Up @@ -291,9 +291,7 @@ export function fetchTotalStaked(

const getTrailingAPI = (endpoint: string) => async () => {
const url = `${endpoint}/v1/metrics/routes/trailing/month`
const res = await fetch(url)
if (!res.ok) throw new Error(res.statusText)
const json = await res.json()
const json = await fetchWithTimeout(url)
return {
count: json?.data?.count ?? 0,
unique_count: json?.data?.unique_count ?? 0
Expand All @@ -305,11 +303,7 @@ const getTrailingAPILegacy = (
startTime: number
) => async () => {
const url = `${endpoint}/v1/metrics/routes?bucket_size=century&start_time=${startTime}`
const res = await fetch(url)
if (!res.ok) {
throw new Error(res.statusText)
}
const json = await res.json()
const json = await fetchWithTimeout(url)
return {
count: json?.data?.[0]?.count ?? 0,
unique_count: json?.data?.[0]?.unique_count ?? 0
Expand Down Expand Up @@ -363,11 +357,7 @@ const getTrailingTopApps = (
const bucketPath = bucketPaths[bucket]
if (!bucketPath) throw new Error('Invalid bucket')
const url = `${endpoint}/v1/metrics/app_name/trailing/${bucketPath}?limit=${limit}`
const res = await fetch(url)
if (!res.ok) {
throw new Error(res.statusText)
}
const json = await res.json()
const json = await fetchWithTimeout(url)
if (!json.data) return {}
return json
}
Expand All @@ -378,11 +368,7 @@ const getTopAppsLegacy = (
limit: number
) => async () => {
const url = `${endpoint}/v1/metrics/app_name?start_time=${startTime}&limit=${limit}&include_unknown=true`
const res = await fetch(url)
if (!res.ok) {
throw new Error(res.statusText)
}
const json = await res.json()
const json = await fetchWithTimeout(url)
if (!json.data) return {}
return json
}
Expand Down Expand Up @@ -452,7 +438,7 @@ export function fetchTrailingTopGenres(
try {
const startTime = getStartTime(bucket)
const url = `${node.endpoint}/v1/metrics/genres?start_time=${startTime}`
const res = await (await fetch(url)).json()
const res = await fetchWithTimeout(url)

const agg: CountRecord = {
Electronic: 0
Expand Down
Loading

0 comments on commit 55df6ce

Please sign in to comment.