Merged in feature/wrap-logging (pull request #2511)

Feature/wrap logging

* feat: change all logging to go through our own logger function so that we can control log levels

* move packages/trpc to using our own logger

* merge


Approved-by: Linus Flood
This commit is contained in:
Joakim Jäderberg
2025-07-03 12:37:04 +00:00
parent 7e32ed294d
commit daf765f3d5
110 changed files with 681 additions and 441 deletions

View File

@@ -1,6 +1,8 @@
import * as Sentry from "@sentry/nextjs"
import { z } from "zod"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
import * as api from "../../../api"
import { protectedProcedure } from "../../../procedures"
import { getOTPState } from "./otp/getOTPState"
@@ -18,13 +20,14 @@ const outputSchema = z.object({
]),
})
const sasLogger = createLogger("SAS")
export const linkAccount = protectedProcedure
.output(outputSchema)
.mutation(async function ({ ctx }) {
const sasAuthToken = await getSasToken()
const { referenceId } = await getOTPState()
console.log("[SAS] link account")
sasLogger.debug("[SAS] link account")
const apiResponse = await api.post(api.endpoints.v1.Profile.link, {
headers: {
@@ -47,7 +50,7 @@ export const linkAccount = protectedProcedure
linkedAndBoosted || linkedWithoutBoost || linkedWithUnknownBoost
if (linked) {
console.log("[SAS] link account done")
sasLogger.debug("[SAS] link account done")
return { linkingState: "linked" }
}
@@ -56,12 +59,12 @@ export const linkAccount = protectedProcedure
const data = badRequestSchema.safeParse(result)
if (!data.success) {
const linkAccountBadRequestSchemaError = `[SAS] failed to parse link account bad request schema ${JSON.stringify(data.error)}`
console.error(linkAccountBadRequestSchemaError)
sasLogger.error(linkAccountBadRequestSchemaError)
Sentry.captureMessage(linkAccountBadRequestSchemaError)
return { linkingState: "error" }
}
console.log("[SAS] link account error with response", result)
sasLogger.error("[SAS] link account error with response", result)
const { errors } = data.data
@@ -89,7 +92,7 @@ export const linkAccount = protectedProcedure
}
const errorMessage = `[SAS] link account error with status code ${apiResponse.status} and response ${await apiResponse.text()}`
console.warn(errorMessage)
sasLogger.error(errorMessage)
Sentry.captureMessage(errorMessage)
return { linkingState: "error" }
})

View File

@@ -4,6 +4,8 @@ import { cookies } from "next/headers"
import { v4 as uuidv4 } from "uuid"
import { z } from "zod"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
import { env } from "../../../../../../env/server"
import { protectedProcedure } from "../../../../../procedures"
import { getSasToken } from "../../getSasToken"
@@ -37,6 +39,7 @@ const failureSchema = z.object({
const outputSchema = z.union([successSchema, failureSchema])
const sasLogger = createLogger("SAS")
export const requestOtp = protectedProcedure
.output(outputSchema)
.mutation(async function () {
@@ -47,8 +50,8 @@ export const requestOtp = protectedProcedure
}
const tokenResponse = await fetchRequestOtp({ sasAuthToken })
console.log(
"[SAS] requestOtp",
sasLogger.debug(
"requestOtp",
tokenResponse.status,
tokenResponse.statusText
)
@@ -56,7 +59,7 @@ export const requestOtp = protectedProcedure
const body = await tokenResponse.json()
const parseResult = outputSchema.safeParse(body)
if (!parseResult.success) {
console.error("[SAS] requestOtp error", body)
sasLogger.error("requestOtp error", body)
if (!tokenResponse.ok) {
throw createError(body)
@@ -67,8 +70,8 @@ export const requestOtp = protectedProcedure
if (parseResult.data.status === "SENT") {
setSASOtpCookie(parseResult.data)
} else {
const sasRequestOtpErrorMessage = `[SAS] requestOtp did not return SENT status with body: ${JSON.stringify(body)}`
console.warn(sasRequestOtpErrorMessage)
const sasRequestOtpErrorMessage = `requestOtp did not return SENT status with body: ${JSON.stringify(body)}`
sasLogger.warn(sasRequestOtpErrorMessage)
Sentry.captureMessage(sasRequestOtpErrorMessage)
}
@@ -87,7 +90,7 @@ function createError(
| RequestOtpGeneralError
): TRPCError {
const errorInfo = parseSASRequestOtpError(errorBody)
console.error("[SAS] createError", errorInfo)
sasLogger.error("createError", errorInfo)
return new TRPCError({
code: "BAD_REQUEST",
cause: errorInfo,
@@ -97,7 +100,7 @@ function createError(
async function fetchRequestOtp({ sasAuthToken }: { sasAuthToken: string }) {
const endpoint = `${env.SAS_API_ENDPOINT}/api/scandic-partnership/customer/send-otp`
console.log("[SAS]: Requesting OTP")
sasLogger.debug("Requesting OTP")
return await fetch(endpoint, {
method: "POST",

View File

@@ -1,5 +1,7 @@
import { z } from "zod"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
export type RequestOtpResponseError = "TOO_MANY_REQUESTS" | "UNKNOWN"
const requestOtpGeneralError = z.enum([
@@ -39,14 +41,14 @@ const SAS_REQUEST_OTP_ERROR_CODES: {
} = {
TOO_MANY_REQUESTS: 10,
}
const sasLogger = createLogger("SAS")
const getErrorCodeByNumber = (number: number): RequestOtpResponseError => {
const v =
Object.entries(SAS_REQUEST_OTP_ERROR_CODES).find(
([_, value]) => value === number
)?.[0] ?? "UNKNOWN"
console.log("[SAS] getErrorCodeByNumber", number, v)
sasLogger.debug("getErrorCodeByNumber", number, v)
return v as RequestOtpResponseError
}

View File

@@ -1,6 +1,8 @@
import { TRPCError } from "@trpc/server"
import { z } from "zod"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
import { env } from "../../../../../../env/server"
import { protectedProcedure } from "../../../../../procedures"
import { getSasToken } from "../../getSasToken"
@@ -29,6 +31,7 @@ const outputSchema = z.object({
databaseUUID: z.string().uuid().optional(),
})
const sasLogger = createLogger("SAS")
export const verifyOtp = protectedProcedure
.input(inputSchema)
.output(outputSchema)
@@ -40,14 +43,14 @@ export const verifyOtp = protectedProcedure
}
const verifyResponse = await fetchVerifyOtp(input)
console.log(
"[SAS] verifyOTP",
sasLogger.debug(
"verifyOTP",
verifyResponse.status,
verifyResponse.statusText
)
if (verifyResponse.status > 499) {
console.error("[SAS] verifyOTP error", await verifyResponse.text())
sasLogger.error("verifyOTP error", await verifyResponse.text())
throw new TRPCError({
code: "SERVICE_UNAVAILABLE",
message: "Error from downstream SAS service",
@@ -55,15 +58,15 @@ export const verifyOtp = protectedProcedure
}
const data = await verifyResponse.json()
console.log("[SAS] verifyOTP data", data)
sasLogger.debug("verifyOTP data", data)
const result = outputSchema.safeParse(data)
if (!result.success) {
console.error("[SAS] verifyOTP error", result.error)
sasLogger.error("verifyOTP error", result.error)
throw createError(data)
}
console.log("[SAS] verifyOTP success")
console.log("[SAS] verifyOTP responding", result.data)
sasLogger.debug("verifyOTP success")
sasLogger.debug("verifyOTP responding", result.data)
return result.data
})

View File

@@ -3,6 +3,7 @@ import { cookies } from "next/headers"
import { z } from "zod"
import { FriendsMembershipLevels } from "@scandic-hotels/common/constants/membershipLevels"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
import * as api from "../../../api"
import { protectedProcedure } from "../../../procedures"
@@ -20,7 +21,7 @@ const notMatchedSchema = z.object({
})
const outputSchema = z.union([matchedSchema, notMatchedSchema])
const sasLogger = createLogger("SAS")
export const performLevelUpgrade = protectedProcedure
.output(outputSchema)
.mutation(async function ({ ctx }) {
@@ -36,7 +37,7 @@ export const performLevelUpgrade = protectedProcedure
}
const currentLevel = profile.data.membership.membershipLevel
console.log("[SAS] tier match started")
sasLogger.debug("tier match started")
const apiResponse = await api.post(api.endpoints.v1.Profile.matchTier, {
headers: {
@@ -55,14 +56,14 @@ export const performLevelUpgrade = protectedProcedure
const updated = apiResponse.status === 200
if (updated) {
console.log("[SAS] tier match complete - boosted")
sasLogger.debug("tier match complete - boosted")
const result = await apiResponse.json()
const user = getUserSchema.parse(result)
if (!user.membership) {
const tierMatchErrorNoMembershipMessage =
"[SAS] tier match error - no membership"
console.log(tierMatchErrorNoMembershipMessage)
"tier match error - no membership"
sasLogger.debug(tierMatchErrorNoMembershipMessage)
Sentry.captureException(new Error(tierMatchErrorNoMembershipMessage))
return { tierMatchState: "error" }
}
@@ -77,21 +78,20 @@ export const performLevelUpgrade = protectedProcedure
const matchedNoChange = apiResponse.status === 204
if (matchedNoChange) {
console.log("[SAS] tier match complete - no change")
sasLogger.debug("tier match complete - no change")
return { tierMatchState: "alreadyMatched" }
}
const notLinked = apiResponse.status === 404
if (notLinked) {
const tierMatchErrorNotLinkedMessage =
"[SAS] tier match error - not linked"
console.warn(tierMatchErrorNotLinkedMessage)
const tierMatchErrorNotLinkedMessage = "tier match error - not linked"
sasLogger.error(tierMatchErrorNotLinkedMessage)
Sentry.captureMessage(tierMatchErrorNotLinkedMessage)
return { tierMatchState: "notLinked" }
}
const tierMatchErrorMessage = `[SAS] tier match error with status code ${apiResponse.status} and response ${await apiResponse.text()}`
console.error(tierMatchErrorMessage)
const tierMatchErrorMessage = `tier match error with status code ${apiResponse.status} and response ${await apiResponse.text()}`
sasLogger.error(tierMatchErrorMessage)
Sentry.captureException(new Error(tierMatchErrorMessage))
return { tierMatchState: "error" }
})

View File

@@ -1,6 +1,8 @@
import * as Sentry from "@sentry/nextjs"
import { z } from "zod"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
import * as api from "../../../api"
import { protectedProcedure } from "../../../procedures"
import { getOTPState } from "./otp/getOTPState"
@@ -14,6 +16,7 @@ const transferPointsInputSchema = z.object({
points: z.number(),
})
const sasLogger = createLogger("SAS")
export const transferPoints = protectedProcedure
.output(outputSchema)
.input(transferPointsInputSchema)
@@ -43,20 +46,20 @@ export const transferPoints = protectedProcedure
const data = badRequestSchema.safeParse(result)
if (!data.success) {
const transferPointsBadRequestSchemaError = `[SAS] failed to parse transfer points bad request schema ${JSON.stringify(data.error)}`
console.error(transferPointsBadRequestSchemaError)
sasLogger.error(transferPointsBadRequestSchemaError)
Sentry.captureMessage(transferPointsBadRequestSchemaError)
return { transferState: "error" }
}
}
if (apiResponse.status === 404) {
const transferPointsNotFoundError = `[SAS] transfer points failed, no active partner link`
console.error(transferPointsNotFoundError)
sasLogger.error(transferPointsNotFoundError)
Sentry.captureMessage(transferPointsNotFoundError)
return { transferState: "notLinked" }
}
const errorMessage = `[SAS] transfer points error with status code ${apiResponse.status} and response ${await apiResponse.text()}`
console.warn(errorMessage)
sasLogger.error(errorMessage)
Sentry.captureMessage(errorMessage)
return { transferState: "error" }
})

View File

@@ -1,5 +1,7 @@
import { z } from "zod"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
import * as api from "../../../api"
import { protectedProcedure } from "../../../procedures"
import { getOTPState } from "./otp/getOTPState"
@@ -8,7 +10,7 @@ import { getSasToken } from "./getSasToken"
const outputSchema = z.object({
linkingState: z.enum(["unlinked", "notLinked", "error"]),
})
const sasLogger = createLogger("SAS")
export const unlinkAccount = protectedProcedure
.output(outputSchema)
.mutation(async function ({ ctx }) {
@@ -29,24 +31,24 @@ export const unlinkAccount = protectedProcedure
})
if (apiResponse.status === 204 || apiResponse.status === 202) {
console.log("[SAS] unlink account success")
sasLogger.debug("unlink account success")
return { linkingState: "unlinked" }
}
if (apiResponse.status === 400) {
const result = await apiResponse.json()
console.log("[SAS] unlink account error with response", result)
sasLogger.debug("unlink account error with response", result)
return { linkingState: "error" }
}
if (apiResponse.status === 404) {
console.log("[SAS] tried unlinking an account that was not linked")
sasLogger.debug("tried unlinking an account that was not linked")
return { linkingState: "notLinked" }
}
console.log(
`[SAS] unlink account error with status code ${apiResponse.status} and response ${await apiResponse.text()}`
sasLogger.debug(
`unlink account error with status code ${apiResponse.status} and response ${await apiResponse.text()}`
)
return { linkingState: "error" }
})