Files
web/packages/trpc/lib/routers/contentstack/reward/utils.ts
Joakim Jäderberg 99537b13e8 Merged in chore/add-error-details-for-sentry (pull request #3378)
Include more details when throwing errors for debugging in Sentry

* WIP throw errors with more details for debugging in Sentry

* Fix throwing response-data

* Clearer message when a response fails

* Add message to errors

* better typings

* .

* Try to send profileID and membershipNumber to Sentry when we fail to parse the apiResponse

* rename notFound -> notFoundError

* Merge branch 'master' of bitbucket.org:scandic-swap/web into chore/add-error-details-for-sentry


Approved-by: Linus Flood
2026-01-12 09:01:44 +00:00

170 lines
4.1 KiB
TypeScript

import { getCacheClient } from "@scandic-hotels/common/dataCache"
import { createCounter } from "@scandic-hotels/common/telemetry"
import * as api from "../../../api"
import { notFoundError } from "../../../errors"
import {
GetRewards as GetRewards,
GetRewardsRef as GetRewardsRef,
} from "../../../graphql/Query/RewardsWithRedeem.graphql"
import { request } from "../../../graphql/request"
import {
generateLoyaltyConfigTag,
generateRefsResponseTag,
} from "../../../utils/generateTag"
import {
rewardRefsSchema,
validateApiAllTiersSchema,
validateCmsRewardsSchema,
} from "./output"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type {
CMSRewardsResponse,
GetRewardRefsSchema,
} from "../../../types/reward"
export function getUniqueRewardIds(rewardIds: string[]) {
const uniqueRewardIds = new Set(rewardIds)
return Array.from(uniqueRewardIds)
}
/**
* Cached for 1 hour.
*/
export async function getCachedAllTierRewards(token: string) {
const cacheClient = await getCacheClient()
return await cacheClient.cacheOrGet(
"getAllTierRewards",
async () => {
const getApiRewardAllTiersCounter = createCounter(
"trpc.api.reward.allTiers"
)
const metricsGetApiRewardAllTiers = getApiRewardAllTiersCounter.init()
metricsGetApiRewardAllTiers.start()
const apiResponse = await api.get(
api.endpoints.v2.Profile.Reward.allTiers,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
)
if (!apiResponse.ok) {
metricsGetApiRewardAllTiers.httpError(apiResponse)
throw apiResponse
}
const data = await apiResponse.json()
const validatedApiAllTierRewards =
validateApiAllTiersSchema.safeParse(data)
if (!validatedApiAllTierRewards.success) {
metricsGetApiRewardAllTiers.validationError(
validatedApiAllTierRewards.error
)
throw validatedApiAllTierRewards.error
}
metricsGetApiRewardAllTiers.success()
return validatedApiAllTierRewards.data
},
"1h"
)
}
export async function getCmsRewards(lang: Lang, rewardIds: string[]) {
if (!rewardIds.length) {
return null
}
const tags = rewardIds.map((id) =>
generateLoyaltyConfigTag(lang, "reward", id)
)
const getContentstackRewardAllRefsCounter = createCounter(
"trpc.contentstack.reward.all.refs"
)
const metricsGetContentstackRewardAllRefs =
getContentstackRewardAllRefsCounter.init({ lang, rewardIds })
metricsGetContentstackRewardAllRefs.start()
const refsResponse = await request<GetRewardRefsSchema>(
GetRewardsRef,
{
locale: lang,
rewardIds,
},
{
key: rewardIds.map((rewardId) => generateRefsResponseTag(lang, rewardId)),
ttl: "max",
}
)
if (!refsResponse.data) {
metricsGetContentstackRewardAllRefs.noDataError()
throw notFoundError({
message: "GetRewardsRef returned no data",
errorDetails: { lang, rewardIds },
})
}
const validatedRefsData = rewardRefsSchema.safeParse(refsResponse)
if (!validatedRefsData.success) {
metricsGetContentstackRewardAllRefs.validationError(validatedRefsData.error)
return null
}
metricsGetContentstackRewardAllRefs.success()
const getContentstackRewardAllCounter = createCounter(
"trpc.contentstack.reward.all"
)
const metricsGetContentstackRewardAll = getContentstackRewardAllCounter.init({
lang,
rewardIds,
})
const cmsRewardsResponse = await request<CMSRewardsResponse>(
GetRewards,
{
locale: lang,
rewardIds,
},
{
key: tags,
ttl: "max",
}
)
if (!cmsRewardsResponse.data) {
metricsGetContentstackRewardAll.noDataError()
throw notFoundError({
message: "GetRewards not found",
errorDetails: { lang, rewardIds },
})
}
const validatedCmsRewards =
validateCmsRewardsSchema.safeParse(cmsRewardsResponse)
if (!validatedCmsRewards.success) {
metricsGetContentstackRewardAll.validationError(validatedCmsRewards.error)
return null
}
metricsGetContentstackRewardAll.success()
return validatedCmsRewards.data
}