Skip to content

Commit

Permalink
Catch and log errors in metadata prop Promises
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobmischka committed Apr 28, 2023
1 parent bc06d60 commit 3b7addb
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 153 deletions.
2 changes: 1 addition & 1 deletion src/classes/IOClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ export class IOClient {
* ```
*/
metadata: this.createIOMethod('DISPLAY_METADATA', {
componentDef: displayMetadata,
componentDef: displayMetadata(this.logger),
propsRequired: true,
}),
/**
Expand Down
349 changes: 197 additions & 152 deletions src/components/displayMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Evt } from 'evt'
import Logger from '../classes/Logger'
import {
T_IO_PROPS,
Serializable,
Expand All @@ -18,185 +19,229 @@ export interface EventualMetaItem {
params?: EventualValue<SerializableRecord>
}

export default function displayMetadata(
props: Pick<T_IO_PROPS<'DISPLAY_METADATA'>, 'layout'> & {
data: EventualMetaItem[]
},
onPropsUpdate?: Evt<T_IO_PROPS<'DISPLAY_METADATA'>>
): { props: T_IO_PROPS<'DISPLAY_METADATA'> } {
const layout = props.layout
const metaItems: EventualMetaItem[] = []
const data: T_IO_PROPS<'DISPLAY_METADATA'>['data'] = props.data.map(
metaItem => {
metaItem = { ...metaItem }

const initialItem: T_IO_PROPS<'DISPLAY_METADATA'>['data'][0] = {
label: metaItem.label,
}

// Currently doing all of this repetitive work separately to leverage
// static type checking, but could be done more dynamically in a loop as well
export default function displaymetadata(logger: Logger) {
return function displayMetadata(
props: Pick<T_IO_PROPS<'DISPLAY_METADATA'>, 'layout'> & {
data: EventualMetaItem[]
},
onPropsUpdate?: Evt<T_IO_PROPS<'DISPLAY_METADATA'>>
): { props: T_IO_PROPS<'DISPLAY_METADATA'> } {
const layout = props.layout
const metaItems: EventualMetaItem[] = []
const data: T_IO_PROPS<'DISPLAY_METADATA'>['data'] = props.data.map(
metaItem => {
metaItem = { ...metaItem }

if ('value' in metaItem && metaItem.value !== undefined) {
if (typeof metaItem.value === 'function') {
metaItem.value = metaItem.value()
const initialItem: T_IO_PROPS<'DISPLAY_METADATA'>['data'][0] = {
label: metaItem.label,
}

if (!(metaItem.value instanceof Promise)) {
initialItem.value = metaItem.value
} else {
initialItem.value = undefined
}
}
// Currently doing all of this repetitive work separately to leverage
// static type checking, but could be done more dynamically in a loop as well

if ('url' in metaItem && metaItem.url !== undefined) {
if (typeof metaItem.url === 'function') {
metaItem.url = metaItem.url()
}
if ('value' in metaItem && metaItem.value !== undefined) {
if (typeof metaItem.value === 'function') {
metaItem.value = metaItem.value()
}

if (!(metaItem.url instanceof Promise)) {
initialItem.url = metaItem.url
} else {
initialItem.url = undefined
if (!(metaItem.value instanceof Promise)) {
initialItem.value = metaItem.value
} else {
initialItem.value = undefined
}
}
}

if ('image' in metaItem && metaItem.image !== undefined) {
if (typeof metaItem.image === 'function') {
metaItem.image = metaItem.image()
}
if ('url' in metaItem && metaItem.url !== undefined) {
if (typeof metaItem.url === 'function') {
metaItem.url = metaItem.url()
}

if (!(metaItem.image instanceof Promise)) {
initialItem.image = metaItem.image
} else {
initialItem.image = undefined
}
}

if ('route' in metaItem && metaItem.route !== undefined) {
if (typeof metaItem.route === 'function') {
metaItem.route = metaItem.route()
if (!(metaItem.url instanceof Promise)) {
initialItem.url = metaItem.url
} else {
initialItem.url = undefined
}
}

if (!(metaItem.route instanceof Promise)) {
initialItem.route = metaItem.route
} else {
initialItem.route = undefined
}
}

if ('action' in metaItem && metaItem.action !== undefined) {
if (typeof metaItem.action === 'function') {
metaItem.action = metaItem.action()
}
if ('image' in metaItem && metaItem.image !== undefined) {
if (typeof metaItem.image === 'function') {
metaItem.image = metaItem.image()
}

if (!(metaItem.action instanceof Promise)) {
initialItem.action = metaItem.action
} else {
initialItem.action = undefined
if (!(metaItem.image instanceof Promise)) {
initialItem.image = metaItem.image
} else {
initialItem.image = undefined
}
}
}

if ('params' in metaItem && metaItem.params !== undefined) {
if (typeof metaItem.params === 'function') {
metaItem.params = metaItem.params()
}
if ('route' in metaItem && metaItem.route !== undefined) {
if (typeof metaItem.route === 'function') {
metaItem.route = metaItem.route()
}

if (!(metaItem.params instanceof Promise)) {
initialItem.params = metaItem.params
} else {
initialItem.params = undefined
if (!(metaItem.route instanceof Promise)) {
initialItem.route = metaItem.route
} else {
initialItem.route = undefined
}
}
}

metaItems.push(metaItem)
if ('action' in metaItem && metaItem.action !== undefined) {
if (typeof metaItem.action === 'function') {
metaItem.action = metaItem.action()
}

return initialItem
}
)

if (onPropsUpdate) {
for (let i = 0; i < metaItems.length; i++) {
const metaItem = metaItems[i]

if ('value' in metaItem) {
if (metaItem.value instanceof Promise) {
metaItem.value.then(resolvedValue => {
data[i].value = resolvedValue
onPropsUpdate?.post({
layout,
data,
})
})
if (!(metaItem.action instanceof Promise)) {
initialItem.action = metaItem.action
} else {
initialItem.action = undefined
}
}
}

if ('url' in metaItem) {
if (metaItem.url instanceof Promise) {
metaItem.url.then(resolvedurl => {
data[i].url = resolvedurl
onPropsUpdate?.post({
layout,
data,
})
})
}
}
if ('params' in metaItem && metaItem.params !== undefined) {
if (typeof metaItem.params === 'function') {
metaItem.params = metaItem.params()
}

if ('image' in metaItem) {
if (metaItem.image instanceof Promise) {
metaItem.image.then(resolvedimage => {
data[i].image = resolvedimage
onPropsUpdate?.post({
layout,
data,
})
})
if (!(metaItem.params instanceof Promise)) {
initialItem.params = metaItem.params
} else {
initialItem.params = undefined
}
}
}

if ('route' in metaItem) {
if (metaItem.route instanceof Promise) {
metaItem.route.then(resolvedroute => {
data[i].route = resolvedroute
onPropsUpdate?.post({
layout,
data,
})
})
}
}
metaItems.push(metaItem)

if ('action' in metaItem) {
if (metaItem.action instanceof Promise) {
metaItem.action.then(resolvedaction => {
data[i].action = resolvedaction
onPropsUpdate?.post({
layout,
data,
})
})
}
return initialItem
}

if ('params' in metaItem) {
if (metaItem.params instanceof Promise) {
metaItem.params.then(resolvedparams => {
data[i].params = resolvedparams
onPropsUpdate?.post({
layout,
data,
})
})
)

if (onPropsUpdate) {
for (let i = 0; i < metaItems.length; i++) {
const metaItem = metaItems[i]

if ('value' in metaItem) {
if (metaItem.value instanceof Promise) {
metaItem.value
.then(resolvedValue => {
data[i].value = resolvedValue
onPropsUpdate?.post({
layout,
data,
})
})
.catch(err => {
logger.error(
'Error updating metadata field "value" with result from Promise:',
err
)
})
}
}

if ('url' in metaItem) {
if (metaItem.url instanceof Promise) {
metaItem.url
.then(resolvedurl => {
data[i].url = resolvedurl
onPropsUpdate?.post({
layout,
data,
})
})
.catch(err => {
logger.error(
'Error updating metadata field "url" with result from Promise:',
err
)
})
}
}

if ('image' in metaItem) {
if (metaItem.image instanceof Promise) {
metaItem.image
.then(resolvedimage => {
data[i].image = resolvedimage
onPropsUpdate?.post({
layout,
data,
})
})
.catch(err => {
logger.error(
'Error updating metadata field "image" with result from Promise:',
err
)
})
}
}

if ('route' in metaItem) {
if (metaItem.route instanceof Promise) {
metaItem.route
.then(resolvedroute => {
data[i].route = resolvedroute
onPropsUpdate?.post({
layout,
data,
})
})
.catch(err => {
logger.error(
'Error updating metadata field "route" with result from Promise:',
err
)
})
}
}

if ('action' in metaItem) {
if (metaItem.action instanceof Promise) {
metaItem.action
.then(resolvedaction => {
data[i].action = resolvedaction
onPropsUpdate?.post({
layout,
data,
})
})
.catch(err => {
logger.error(
'Error updating metadata field "action" with result from Promise:',
err
)
})
}
}

if ('params' in metaItem) {
if (metaItem.params instanceof Promise) {
metaItem.params
.then(resolvedparams => {
data[i].params = resolvedparams
onPropsUpdate?.post({
layout,
data,
})
})
.catch(err => {
logger.error(
'Error updating metadata field "params" with result from Promise:',
err
)
})
}
}
}
}
}

return {
props: {
data,
layout,
},
return {
props: {
data,
layout,
},
}
}
}
Loading

0 comments on commit 3b7addb

Please sign in to comment.