feat: harmonize log and metrics
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
import { metrics } from "@opentelemetry/api"
|
||||
|
||||
import { countries } from "@/constants/countries"
|
||||
import * as api from "@/lib/api"
|
||||
import { dt } from "@/lib/dt"
|
||||
import { createCounter } from "@/server/telemetry"
|
||||
import {
|
||||
languageProtectedProcedure,
|
||||
protectedProcedure,
|
||||
@@ -10,8 +7,6 @@ import {
|
||||
safeProtectedProcedure,
|
||||
} from "@/server/trpc"
|
||||
|
||||
import { cache } from "@/utils/cache"
|
||||
import * as maskValue from "@/utils/maskValue"
|
||||
import { isValidSession } from "@/utils/session"
|
||||
import { getFriendsMembership, getMembershipCards } from "@/utils/user"
|
||||
|
||||
@@ -20,277 +15,21 @@ import {
|
||||
getSavedPaymentCardsInput,
|
||||
staysInput,
|
||||
} from "./input"
|
||||
import { getFriendTransactionsSchema } from "./output"
|
||||
import {
|
||||
creditCardsSchema,
|
||||
getFriendTransactionsSchema,
|
||||
getStaysSchema,
|
||||
getUserSchema,
|
||||
} from "./output"
|
||||
import { updateStaysBookingUrl } from "./utils"
|
||||
|
||||
import type { Session } from "next-auth"
|
||||
getCreditCards,
|
||||
getPreviousStays,
|
||||
getUpcomingStays,
|
||||
getVerifiedUser,
|
||||
parsedUser,
|
||||
updateStaysBookingUrl,
|
||||
} from "./utils"
|
||||
|
||||
import type {
|
||||
LoginType,
|
||||
TrackingSDKUserData,
|
||||
} from "@/types/components/tracking"
|
||||
import { Transactions } from "@/types/enums/transactions"
|
||||
import type { User } from "@/types/user"
|
||||
|
||||
// OpenTelemetry metrics: User
|
||||
const meter = metrics.getMeter("trpc.user")
|
||||
const getVerifiedUserCounter = meter.createCounter("trpc.user.get")
|
||||
const getVerifiedUserSuccessCounter = meter.createCounter(
|
||||
"trpc.user.get-success"
|
||||
)
|
||||
const getVerifiedUserFailCounter = meter.createCounter("trpc.user.get-fail")
|
||||
|
||||
// OpenTelemetry metrics: Stays
|
||||
const getPreviousStaysCounter = meter.createCounter("trpc.user.stays.previous")
|
||||
const getPreviousStaysSuccessCounter = meter.createCounter(
|
||||
"trpc.user.stays.previous-success"
|
||||
)
|
||||
const getPreviousStaysFailCounter = meter.createCounter(
|
||||
"trpc.user.stays.previous-fail"
|
||||
)
|
||||
const getUpcomingStaysCounter = meter.createCounter("trpc.user.stays.upcoming")
|
||||
const getUpcomingStaysSuccessCounter = meter.createCounter(
|
||||
"trpc.user.stays.upcoming-success"
|
||||
)
|
||||
const getUpcomingStaysFailCounter = meter.createCounter(
|
||||
"trpc.user.stays.upcoming-fail"
|
||||
)
|
||||
|
||||
// OpenTelemetry metrics: Transactions
|
||||
const getFriendTransactionsCounter = meter.createCounter(
|
||||
"trpc.user.transactions.friendTransactions"
|
||||
)
|
||||
const getFriendTransactionsSuccessCounter = meter.createCounter(
|
||||
"trpc.user.transactions.friendTransactions-success"
|
||||
)
|
||||
const getFriendTransactionsFailCounter = meter.createCounter(
|
||||
"trpc.user.transactions.friendTransactions-fail"
|
||||
)
|
||||
|
||||
// OpenTelemetry metrics: Credit Cards
|
||||
const getCreditCardsCounter = meter.createCounter("trpc.user.creditCards")
|
||||
const getCreditCardsSuccessCounter = meter.createCounter(
|
||||
"trpc.user.creditCards-success"
|
||||
)
|
||||
const getCreditCardsFailCounter = meter.createCounter(
|
||||
"trpc.user.creditCards-fail"
|
||||
)
|
||||
|
||||
export const getVerifiedUser = cache(
|
||||
async ({
|
||||
session,
|
||||
includeExtendedPartnerData,
|
||||
}: {
|
||||
session: Session
|
||||
includeExtendedPartnerData?: boolean
|
||||
}) => {
|
||||
const now = Date.now()
|
||||
if (session.token.expires_at && session.token.expires_at < now) {
|
||||
return { error: true, cause: "token_expired" } as const
|
||||
}
|
||||
getVerifiedUserCounter.add(1)
|
||||
console.info("api.user.profile getVerifiedUser start", JSON.stringify({}))
|
||||
const apiResponse = await api.get(
|
||||
api.endpoints.v2.Profile.profile,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${session.token.access_token}`,
|
||||
},
|
||||
},
|
||||
includeExtendedPartnerData
|
||||
? { includes: "extendedPartnerInformation" }
|
||||
: {}
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
const text = await apiResponse.text()
|
||||
getVerifiedUserFailCounter.add(1, {
|
||||
error_type: "http_error",
|
||||
error: JSON.stringify({
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
}),
|
||||
})
|
||||
console.error(
|
||||
"api.user.profile getVerifiedUser error",
|
||||
JSON.stringify({
|
||||
error: {
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
},
|
||||
})
|
||||
)
|
||||
if (apiResponse.status === 401) {
|
||||
return { error: true, cause: "unauthorized" } as const
|
||||
} else if (apiResponse.status === 403) {
|
||||
return { error: true, cause: "forbidden" } as const
|
||||
} else if (apiResponse.status === 404) {
|
||||
return { error: true, cause: "notfound" } as const
|
||||
}
|
||||
return {
|
||||
error: true,
|
||||
cause: "unknown",
|
||||
status: apiResponse.status,
|
||||
} as const
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
if (!apiJson.data?.attributes) {
|
||||
getVerifiedUserFailCounter.add(1, {
|
||||
error_type: "data_error",
|
||||
})
|
||||
console.error(
|
||||
"api.user.profile getVerifiedUser data error",
|
||||
JSON.stringify({
|
||||
apiResponse: apiJson,
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const verifiedData = getUserSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
getVerifiedUserFailCounter.add(1, {
|
||||
error_type: "validation_error",
|
||||
error: JSON.stringify(verifiedData.error),
|
||||
})
|
||||
console.error(
|
||||
"api.user.profile validation error",
|
||||
JSON.stringify({
|
||||
errors: verifiedData.error,
|
||||
apiResponse: apiJson,
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
getVerifiedUserSuccessCounter.add(1)
|
||||
console.info("api.user.profile getVerifiedUser success", JSON.stringify({}))
|
||||
return verifiedData
|
||||
}
|
||||
)
|
||||
|
||||
export function parsedUser(data: User, isMFA: boolean) {
|
||||
const country = countries.find((c) => c.code === data.address?.countryCode)
|
||||
|
||||
const user = {
|
||||
address: {
|
||||
city: data.address?.city,
|
||||
country: country?.name ?? "",
|
||||
countryCode: data.address?.countryCode,
|
||||
streetAddress: data.address?.streetAddress,
|
||||
zipCode: data.address?.zipCode,
|
||||
},
|
||||
dateOfBirth: data.dateOfBirth,
|
||||
email: data.email,
|
||||
firstName: data.firstName,
|
||||
language: data.language,
|
||||
lastName: data.lastName,
|
||||
membershipNumber: data.membershipNumber,
|
||||
membership: getFriendsMembership(data.loyalty),
|
||||
loyalty: data.loyalty,
|
||||
name: `${data.firstName} ${data.lastName}`,
|
||||
phoneNumber: data.phoneNumber,
|
||||
profileId: data.profileId,
|
||||
}
|
||||
|
||||
if (!isMFA) {
|
||||
if (user.address.city) {
|
||||
user.address.city = maskValue.text(user.address.city)
|
||||
}
|
||||
if (user.address.streetAddress) {
|
||||
user.address.streetAddress = maskValue.text(user.address.streetAddress)
|
||||
}
|
||||
|
||||
user.address.zipCode = data.address?.zipCode
|
||||
? maskValue.text(data.address.zipCode)
|
||||
: ""
|
||||
|
||||
user.dateOfBirth = maskValue.all(user.dateOfBirth)
|
||||
|
||||
user.email = maskValue.email(user.email)
|
||||
|
||||
user.phoneNumber = user.phoneNumber ? maskValue.phone(user.phoneNumber) : ""
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
const getCreditCards = cache(
|
||||
async ({
|
||||
session,
|
||||
onlyNonExpired,
|
||||
}: {
|
||||
session: Session
|
||||
onlyNonExpired?: boolean
|
||||
}) => {
|
||||
getCreditCardsCounter.add(1)
|
||||
console.info("api.profile.creditCards start", JSON.stringify({}))
|
||||
const apiResponse = await api.get(api.endpoints.v1.Profile.creditCards, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${session.token.access_token}`,
|
||||
},
|
||||
})
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
const text = await apiResponse.text()
|
||||
getCreditCardsFailCounter.add(1, {
|
||||
error_type: "http_error",
|
||||
error: JSON.stringify({
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
}),
|
||||
})
|
||||
console.error(
|
||||
"api.profile.creditCards error ",
|
||||
JSON.stringify({
|
||||
error: {
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
},
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const verifiedData = creditCardsSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
getCreditCardsFailCounter.add(1, {
|
||||
error_type: "validation_error",
|
||||
error: JSON.stringify(verifiedData.error),
|
||||
})
|
||||
console.error(
|
||||
"api.profile.creditCards validation error ",
|
||||
JSON.stringify({ error: verifiedData.error })
|
||||
)
|
||||
return null
|
||||
}
|
||||
getCreditCardsSuccessCounter.add(1)
|
||||
console.info("api.profile.creditCards success", JSON.stringify({}))
|
||||
|
||||
return verifiedData.data.data.filter((card) => {
|
||||
if (onlyNonExpired) {
|
||||
try {
|
||||
const expirationDate = dt(card.expirationDate).startOf("day")
|
||||
const currentDate = dt().startOf("day")
|
||||
return expirationDate > currentDate
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
export const userQueryRouter = router({
|
||||
get: protectedProcedure
|
||||
@@ -385,11 +124,20 @@ export const userQueryRouter = router({
|
||||
return membershipLevel
|
||||
}),
|
||||
userTrackingInfo: safeProtectedProcedure.query(async function ({ ctx }) {
|
||||
const userTrackingInfoCounter = createCounter("user", "userTrackingInfo")
|
||||
const metricsUserTrackingInfo = userTrackingInfoCounter.init()
|
||||
|
||||
metricsUserTrackingInfo.start()
|
||||
|
||||
const notLoggedInUserTrackingData: TrackingSDKUserData = {
|
||||
loginStatus: "Non-logged in",
|
||||
}
|
||||
|
||||
if (!isValidSession(ctx.session)) {
|
||||
metricsUserTrackingInfo.success({
|
||||
reason: "invalid session",
|
||||
data: notLoggedInUserTrackingData,
|
||||
})
|
||||
return notLoggedInUserTrackingData
|
||||
}
|
||||
|
||||
@@ -397,62 +145,24 @@ export const userQueryRouter = router({
|
||||
const verifiedUserData = await getVerifiedUser({ session: ctx.session })
|
||||
|
||||
if (!verifiedUserData || "error" in verifiedUserData) {
|
||||
return notLoggedInUserTrackingData
|
||||
}
|
||||
|
||||
const params = new URLSearchParams()
|
||||
params.set("limit", "1")
|
||||
getPreviousStaysCounter.add(1, { query: JSON.stringify({ params }) })
|
||||
console.info(
|
||||
"api.booking.stays.past start",
|
||||
JSON.stringify({ query: { params } })
|
||||
)
|
||||
const previousStaysResponse = await api.get(
|
||||
api.endpoints.v1.Booking.Stays.past,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
},
|
||||
params
|
||||
)
|
||||
|
||||
if (!previousStaysResponse.ok) {
|
||||
getPreviousStaysFailCounter.add(1, {
|
||||
error_type: "http_error",
|
||||
error: JSON.stringify({
|
||||
status: previousStaysResponse.status,
|
||||
statusText: previousStaysResponse.statusText,
|
||||
}),
|
||||
metricsUserTrackingInfo.success({
|
||||
reason: "invalid user data",
|
||||
data: notLoggedInUserTrackingData,
|
||||
})
|
||||
console.error(
|
||||
"api.booking.stays.past error",
|
||||
JSON.stringify({
|
||||
error: {
|
||||
status: previousStaysResponse.status,
|
||||
statusText: previousStaysResponse.statusText,
|
||||
},
|
||||
})
|
||||
)
|
||||
return notLoggedInUserTrackingData
|
||||
}
|
||||
|
||||
const previousStaysApiJson = await previousStaysResponse.json()
|
||||
const verifiedPreviousStaysData =
|
||||
getStaysSchema.safeParse(previousStaysApiJson)
|
||||
if (!verifiedPreviousStaysData.success) {
|
||||
getPreviousStaysFailCounter.add(1, {
|
||||
error_type: "validation_error",
|
||||
error: JSON.stringify(verifiedPreviousStaysData.error),
|
||||
const previousStaysData = await getPreviousStays(
|
||||
ctx.session.token.access_token,
|
||||
1
|
||||
)
|
||||
if (!previousStaysData) {
|
||||
metricsUserTrackingInfo.success({
|
||||
reason: "no previous stays data",
|
||||
data: notLoggedInUserTrackingData,
|
||||
})
|
||||
console.error(
|
||||
"api.booking.stays.past validation error, ",
|
||||
JSON.stringify({ error: verifiedPreviousStaysData.error })
|
||||
)
|
||||
return notLoggedInUserTrackingData
|
||||
}
|
||||
getPreviousStaysSuccessCounter.add(1)
|
||||
console.info("api.booking.stays.past success", JSON.stringify({}))
|
||||
|
||||
const membership = getFriendsMembership(verifiedUserData.data.loyalty)
|
||||
|
||||
@@ -462,13 +172,19 @@ export const userQueryRouter = router({
|
||||
memberId: verifiedUserData.data.profileId,
|
||||
membershipNumber: membership?.membershipNumber,
|
||||
memberLevel: membership?.membershipLevel,
|
||||
noOfNightsStayed: verifiedPreviousStaysData.data.links?.totalCount ?? 0,
|
||||
noOfNightsStayed: previousStaysData.links?.totalCount ?? 0,
|
||||
totalPointsAvailableToSpend: membership?.currentPoints,
|
||||
loginAction: "login success",
|
||||
}
|
||||
|
||||
metricsUserTrackingInfo.success({
|
||||
reason: "valid logged in",
|
||||
data: loggedInUserTrackingData,
|
||||
})
|
||||
|
||||
return loggedInUserTrackingData
|
||||
} catch (error) {
|
||||
console.error("Error in userTrackingInfo:", error)
|
||||
metricsUserTrackingInfo.fail(error)
|
||||
return notLoggedInUserTrackingData
|
||||
}
|
||||
}),
|
||||
@@ -479,93 +195,31 @@ export const userQueryRouter = router({
|
||||
.query(async ({ ctx, input }) => {
|
||||
const { limit, cursor, lang } = input
|
||||
const language = lang || ctx.lang
|
||||
const params: Record<string, string> = { limit }
|
||||
if (cursor) {
|
||||
params.offset = cursor
|
||||
}
|
||||
getPreviousStaysCounter.add(1, { query: JSON.stringify({ params }) })
|
||||
console.info(
|
||||
"api.booking.stays.past start",
|
||||
JSON.stringify({ query: { params } })
|
||||
)
|
||||
|
||||
const apiResponse = await api.get(
|
||||
api.endpoints.v1.Booking.Stays.past,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
},
|
||||
params
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
const text = await apiResponse.text()
|
||||
getPreviousStaysFailCounter.add(1, {
|
||||
query: JSON.stringify({ params }),
|
||||
error_type: "http_error",
|
||||
error: JSON.stringify({
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
}),
|
||||
})
|
||||
console.error(
|
||||
"api.booking.stays.past error ",
|
||||
JSON.stringify({
|
||||
query: { params },
|
||||
error: {
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
},
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
|
||||
const verifiedData = getStaysSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
getPreviousStaysFailCounter.add(1, {
|
||||
query: JSON.stringify({ params }),
|
||||
error_type: "validation_error",
|
||||
error: JSON.stringify(verifiedData.error),
|
||||
})
|
||||
console.error(
|
||||
"api.booking.stays.past validation error ",
|
||||
JSON.stringify({
|
||||
query: { params },
|
||||
error: verifiedData.error,
|
||||
})
|
||||
)
|
||||
|
||||
return null
|
||||
}
|
||||
getPreviousStaysSuccessCounter.add(1, {
|
||||
query: JSON.stringify({ params }),
|
||||
})
|
||||
console.info(
|
||||
"api.booking.stays.past success",
|
||||
JSON.stringify({ query: { params } })
|
||||
)
|
||||
const nextCursor =
|
||||
verifiedData.data.links &&
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
? verifiedData.data.links.offset
|
||||
: undefined
|
||||
|
||||
const updatedData = await updateStaysBookingUrl(
|
||||
verifiedData.data.data,
|
||||
const data = await getPreviousStays(
|
||||
ctx.session.token.access_token,
|
||||
language
|
||||
limit,
|
||||
cursor
|
||||
)
|
||||
|
||||
return {
|
||||
data: updatedData,
|
||||
nextCursor,
|
||||
if (data) {
|
||||
const nextCursor =
|
||||
data.links && data.links.offset < data.links.totalCount
|
||||
? data.links.offset
|
||||
: undefined
|
||||
|
||||
const updatedData = await updateStaysBookingUrl(
|
||||
data.data,
|
||||
ctx.session,
|
||||
language
|
||||
)
|
||||
|
||||
return {
|
||||
data: updatedData,
|
||||
nextCursor,
|
||||
}
|
||||
}
|
||||
return null
|
||||
}),
|
||||
|
||||
upcoming: languageProtectedProcedure
|
||||
@@ -573,92 +227,31 @@ export const userQueryRouter = router({
|
||||
.query(async ({ ctx, input }) => {
|
||||
const { limit, cursor, lang } = input
|
||||
const language = lang || ctx.lang
|
||||
const params: Record<string, string> = { limit }
|
||||
if (cursor) {
|
||||
params.offset = cursor
|
||||
}
|
||||
getUpcomingStaysCounter.add(1, {
|
||||
query: JSON.stringify({ params }),
|
||||
})
|
||||
console.info(
|
||||
"api.booking.stays.future start",
|
||||
JSON.stringify({ query: { params } })
|
||||
)
|
||||
const apiResponse = await api.get(
|
||||
api.endpoints.v1.Booking.Stays.future,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.session.token.access_token}`,
|
||||
},
|
||||
},
|
||||
params
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
const text = await apiResponse.text()
|
||||
getUpcomingStaysFailCounter.add(1, {
|
||||
query: JSON.stringify({ params }),
|
||||
error_type: "http_error",
|
||||
error: JSON.stringify({
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
}),
|
||||
})
|
||||
console.error(
|
||||
"api.booking.stays.future error ",
|
||||
JSON.stringify({
|
||||
query: { params },
|
||||
error_type: "http_error",
|
||||
error: {
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
},
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const verifiedData = getStaysSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
getUpcomingStaysFailCounter.add(1, {
|
||||
query: JSON.stringify({ params }),
|
||||
error_type: "validation_error",
|
||||
error: JSON.stringify(verifiedData.error),
|
||||
})
|
||||
console.error(
|
||||
"api.booking.stays.future validation error ",
|
||||
JSON.stringify({
|
||||
query: { params },
|
||||
error: verifiedData.error,
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
getUpcomingStaysSuccessCounter.add(1, {
|
||||
query: JSON.stringify({ params }),
|
||||
})
|
||||
console.info("api.booking.stays.future success", {
|
||||
query: JSON.stringify({ params }),
|
||||
})
|
||||
const nextCursor =
|
||||
verifiedData.data.links &&
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
? verifiedData.data.links.offset
|
||||
: undefined
|
||||
|
||||
const updatedData = await updateStaysBookingUrl(
|
||||
verifiedData.data.data,
|
||||
const data = await getUpcomingStays(
|
||||
ctx.session.token.access_token,
|
||||
language
|
||||
limit,
|
||||
cursor
|
||||
)
|
||||
|
||||
return {
|
||||
data: updatedData,
|
||||
nextCursor,
|
||||
if (data) {
|
||||
const nextCursor =
|
||||
data.links && data.links.offset < data.links.totalCount
|
||||
? data.links.offset
|
||||
: undefined
|
||||
|
||||
const updatedData = await updateStaysBookingUrl(
|
||||
data.data,
|
||||
ctx.session,
|
||||
language
|
||||
)
|
||||
|
||||
return {
|
||||
data: updatedData,
|
||||
nextCursor,
|
||||
}
|
||||
}
|
||||
return null
|
||||
}),
|
||||
}),
|
||||
transaction: router({
|
||||
@@ -667,11 +260,18 @@ export const userQueryRouter = router({
|
||||
.query(async ({ ctx, input }) => {
|
||||
const { limit, page } = input
|
||||
|
||||
getFriendTransactionsCounter.add(1)
|
||||
console.info(
|
||||
"api.transaction.friendTransactions start",
|
||||
JSON.stringify({})
|
||||
const friendTransactionsCounter = createCounter(
|
||||
"trpc.user.transactions",
|
||||
"friendTransactions"
|
||||
)
|
||||
|
||||
const metricsFriendTransactions = friendTransactionsCounter.init({
|
||||
limit,
|
||||
page,
|
||||
})
|
||||
|
||||
metricsFriendTransactions.start()
|
||||
|
||||
const apiResponse = await api.get(
|
||||
api.endpoints.v1.Profile.Transaction.friendTransactions,
|
||||
{
|
||||
@@ -682,61 +282,20 @@ export const userQueryRouter = router({
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
// switch (apiResponse.status) {
|
||||
// case 400:
|
||||
// throw badRequestError()
|
||||
// case 401:
|
||||
// throw unauthorizedError()
|
||||
// case 403:
|
||||
// throw forbiddenError()
|
||||
// default:
|
||||
// throw internalServerError()
|
||||
// }
|
||||
const text = await apiResponse.text()
|
||||
getFriendTransactionsFailCounter.add(1, {
|
||||
error_type: "http_error",
|
||||
error: JSON.stringify({
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
}),
|
||||
})
|
||||
console.error(
|
||||
"api.transaction.friendTransactions error ",
|
||||
JSON.stringify({
|
||||
error: {
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
},
|
||||
})
|
||||
)
|
||||
await metricsFriendTransactions.httpError(apiResponse)
|
||||
return null
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
const verifiedData = getFriendTransactionsSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
getFriendTransactionsFailCounter.add(1, {
|
||||
error_type: "validation_error",
|
||||
error: JSON.stringify(verifiedData.error),
|
||||
})
|
||||
console.error(
|
||||
"api.transaction.friendTransactions validation error ",
|
||||
JSON.stringify({ error: verifiedData.error })
|
||||
)
|
||||
metricsFriendTransactions.validationError(verifiedData.error)
|
||||
return null
|
||||
}
|
||||
|
||||
getFriendTransactionsSuccessCounter.add(1)
|
||||
console.info(
|
||||
"api.transaction.friendTransactions success",
|
||||
JSON.stringify({})
|
||||
)
|
||||
|
||||
const updatedData = await updateStaysBookingUrl(
|
||||
verifiedData.data.data,
|
||||
ctx.session.token.access_token,
|
||||
ctx.session,
|
||||
ctx.lang
|
||||
)
|
||||
|
||||
@@ -763,7 +322,7 @@ export const userQueryRouter = router({
|
||||
|
||||
const slicedData = pageData.slice(limit * (page - 1), limit * page)
|
||||
|
||||
return {
|
||||
const result = {
|
||||
data: {
|
||||
transactions: slicedData.map(({ type, attributes }) => {
|
||||
return {
|
||||
@@ -786,6 +345,10 @@ export const userQueryRouter = router({
|
||||
totalPages: Math.ceil(pageData.length / limit),
|
||||
},
|
||||
}
|
||||
|
||||
metricsFriendTransactions.success()
|
||||
|
||||
return result
|
||||
}),
|
||||
}),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user