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
This commit is contained in:
@@ -5,7 +5,7 @@ import { env } from "../../../../env/server"
|
||||
import { router } from "../../.."
|
||||
import * as api from "../../../api"
|
||||
import { Transactions } from "../../../enums/transactions"
|
||||
import { notFound } from "../../../errors"
|
||||
import { notFoundError } from "../../../errors"
|
||||
import {
|
||||
languageProtectedProcedure,
|
||||
protectedProcedure,
|
||||
@@ -47,7 +47,7 @@ export const userQueryRouter = router({
|
||||
.query(async function getUser({ ctx }) {
|
||||
const user = await ctx.getScandicUser()
|
||||
if (!user) {
|
||||
throw notFound()
|
||||
throw notFoundError()
|
||||
}
|
||||
|
||||
return parsedUser(user, !ctx.isMFA)
|
||||
@@ -68,7 +68,7 @@ export const userQueryRouter = router({
|
||||
getBasic: protectedProcedure.query(async function getBasicUser({ ctx }) {
|
||||
const user = await ctx.getScandicBasicUser()
|
||||
if (!user) {
|
||||
throw notFound()
|
||||
throw notFoundError()
|
||||
}
|
||||
|
||||
return user
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
import * as Sentry from "@sentry/nextjs"
|
||||
|
||||
import { createCounter } from "@scandic-hotels/common/telemetry"
|
||||
|
||||
import * as api from "../../../api"
|
||||
import { cache } from "../../../DUPLICATED/cache"
|
||||
import { serverErrorByStatus, sessionExpiredError } from "../../../errors"
|
||||
import {
|
||||
extractResponseDetails,
|
||||
serverErrorByStatus,
|
||||
sessionExpiredError,
|
||||
} from "../../../errors"
|
||||
import { getBasicUserSchema } from "../output"
|
||||
|
||||
import type z from "zod"
|
||||
|
||||
import type { DeepPartial } from "../../../types/deepPartial"
|
||||
|
||||
export const getBasicUser = cache(
|
||||
async ({
|
||||
token,
|
||||
@@ -30,12 +40,17 @@ export const getBasicUser = cache(
|
||||
if (!apiResponse.ok) {
|
||||
await metricsGetBasicUser.httpError(apiResponse)
|
||||
|
||||
throw serverErrorByStatus(apiResponse.status, apiResponse)
|
||||
throw serverErrorByStatus(
|
||||
apiResponse.status,
|
||||
await extractResponseDetails(apiResponse),
|
||||
"getBasicUser failed"
|
||||
)
|
||||
}
|
||||
const apiJson = await apiResponse.json()
|
||||
|
||||
const verifiedData = getBasicUserSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
addUserToSentry(apiJson)
|
||||
metricsGetBasicUser.validationError(verifiedData.error)
|
||||
throw verifiedData.error
|
||||
}
|
||||
@@ -45,3 +60,18 @@ export const getBasicUser = cache(
|
||||
return verifiedData.data
|
||||
}
|
||||
)
|
||||
|
||||
function addUserToSentry(apiJson: unknown) {
|
||||
const typedData = apiJson as DeepPartial<z.input<typeof getBasicUserSchema>>
|
||||
if (
|
||||
typeof typedData?.profileId === "undefined" ||
|
||||
typeof typedData?.membershipNumber === "undefined"
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
Sentry.setUser({
|
||||
id: typedData?.profileId,
|
||||
username: typedData?.membershipNumber,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
import * as Sentry from "@sentry/nextjs"
|
||||
|
||||
import { createCounter } from "@scandic-hotels/common/telemetry"
|
||||
|
||||
import * as api from "../../../api"
|
||||
import { cache } from "../../../DUPLICATED/cache"
|
||||
import {
|
||||
extractResponseDetails,
|
||||
internalServerError,
|
||||
serverErrorByStatus,
|
||||
sessionExpiredError,
|
||||
} from "../../../errors"
|
||||
import { getUserSchema } from "../output"
|
||||
|
||||
import type { z } from "zod"
|
||||
|
||||
import type { DeepPartial } from "../../../types/deepPartial"
|
||||
|
||||
export const getVerifiedUser = cache(
|
||||
async ({
|
||||
token,
|
||||
@@ -42,7 +49,11 @@ export const getVerifiedUser = cache(
|
||||
if (!apiResponse.ok) {
|
||||
await metricsGetVerifiedUser.httpError(apiResponse)
|
||||
|
||||
throw serverErrorByStatus(apiResponse.status, apiResponse)
|
||||
throw serverErrorByStatus(
|
||||
apiResponse.status,
|
||||
await extractResponseDetails(apiResponse),
|
||||
"getVerifiedUser failed"
|
||||
)
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
@@ -57,13 +68,29 @@ export const getVerifiedUser = cache(
|
||||
}
|
||||
|
||||
const verifiedData = getUserSchema.safeParse(apiJson)
|
||||
|
||||
if (!verifiedData.success) {
|
||||
addUserToSentry(apiJson)
|
||||
metricsGetVerifiedUser.validationError(verifiedData.error)
|
||||
throw verifiedData.error
|
||||
}
|
||||
|
||||
metricsGetVerifiedUser.success()
|
||||
|
||||
return verifiedData.data
|
||||
}
|
||||
)
|
||||
|
||||
function addUserToSentry(apiJson: unknown) {
|
||||
const typedData = apiJson as DeepPartial<z.input<typeof getUserSchema>>
|
||||
if (
|
||||
typeof typedData.data?.attributes?.profileId === "undefined" ||
|
||||
typeof typedData.data?.attributes?.membershipNumber === "undefined"
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
Sentry.setUser({
|
||||
id: typedData?.data?.attributes?.profileId,
|
||||
username: typedData?.data?.attributes?.membershipNumber,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user