mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-28 20:49:34 -05:00
feat: pino logger for formbricks (#2296)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
committed by
GitHub
parent
b72cda05c1
commit
dadc337955
@@ -1,6 +1,7 @@
|
||||
import Stripe from "stripe";
|
||||
|
||||
import { env } from "@formbricks/lib/env";
|
||||
import { logger } from "@formbricks/lib/utils/logger";
|
||||
|
||||
import { handleCheckoutSessionCompleted } from "../handlers/checkoutSessionCompleted";
|
||||
import { handleSubscriptionUpdatedOrCreated } from "../handlers/subscriptionCreatedOrUpdated";
|
||||
@@ -19,7 +20,7 @@ const webhookHandler = async (requestBody: string, stripeSignature: string) => {
|
||||
event = stripe.webhooks.constructEvent(requestBody, stripeSignature, webhookSecret);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : "Unknown error";
|
||||
if (err! instanceof Error) console.log(err);
|
||||
if (err! instanceof Error) logger.error(err);
|
||||
return { status: 400, message: `Webhook Error: ${errorMessage}` };
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
getTeam,
|
||||
updateTeam,
|
||||
} from "@formbricks/lib/team/service";
|
||||
import { logger } from "@formbricks/lib/utils/logger";
|
||||
|
||||
import { ProductFeatureKeys, StripePriceLookupKeys, StripeProductNames } from "../lib/constants";
|
||||
import { reportUsage } from "../lib/reportUsage";
|
||||
@@ -45,7 +46,7 @@ export const handleSubscriptionUpdatedOrCreated = async (event: Stripe.Event) =>
|
||||
}
|
||||
|
||||
if (!teamId) {
|
||||
console.error("No teamId found in subscription");
|
||||
logger.error("No teamId found in subscription");
|
||||
return { status: 400, message: "skipping, no teamId found" };
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import Stripe from "stripe";
|
||||
|
||||
import { env } from "@formbricks/lib/env";
|
||||
import { getTeam, updateTeam } from "@formbricks/lib/team/service";
|
||||
import { logger } from "@formbricks/lib/utils/logger";
|
||||
|
||||
import { ProductFeatureKeys, StripeProductNames } from "../lib/constants";
|
||||
import { unsubscribeCoreAndAppSurveyFeatures, unsubscribeLinkSurveyProFeatures } from "../lib/downgradePlan";
|
||||
@@ -15,7 +16,7 @@ export const handleSubscriptionDeleted = async (event: Stripe.Event) => {
|
||||
const stripeSubscriptionObject = event.data.object as Stripe.Subscription;
|
||||
const teamId = stripeSubscriptionObject.metadata.teamId;
|
||||
if (!teamId) {
|
||||
console.error("No teamId found in subscription");
|
||||
logger.error("No teamId found in subscription");
|
||||
return { status: 400, message: "skipping, no teamId found" };
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import Stripe from "stripe";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { env } from "@formbricks/lib/env";
|
||||
import { getTeam } from "@formbricks/lib/team/service";
|
||||
import { logger } from "@formbricks/lib/utils/logger";
|
||||
|
||||
import { StripePriceLookupKeys } from "./constants";
|
||||
|
||||
@@ -177,7 +178,7 @@ export const createSubscription = async (
|
||||
url: "",
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
logger.error(err);
|
||||
return {
|
||||
status: 500,
|
||||
data: "Something went wrong!",
|
||||
|
||||
@@ -3,6 +3,7 @@ import Stripe from "stripe";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { env } from "@formbricks/lib/env";
|
||||
import { getTeam, updateTeam } from "@formbricks/lib/team/service";
|
||||
import { logger } from "@formbricks/lib/utils/logger";
|
||||
|
||||
import { StripePriceLookupKeys } from "./constants";
|
||||
import { getFirstOfNextMonthTimestamp } from "./createSubscription";
|
||||
@@ -112,7 +113,7 @@ export const removeSubscription = async (
|
||||
url: "",
|
||||
};
|
||||
} catch (err) {
|
||||
console.log("Error in removing subscription:", err);
|
||||
logger.error(`Error in removing subscription: ${err}`);
|
||||
|
||||
return {
|
||||
status: 500,
|
||||
|
||||
@@ -18,6 +18,7 @@ import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/errors";
|
||||
|
||||
import { ITEMS_PER_PAGE, SERVICES_REVALIDATION_INTERVAL } from "../constants";
|
||||
import { formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { actionClassCache } from "./cache";
|
||||
|
||||
@@ -176,7 +177,7 @@ export const createActionClass = async (
|
||||
|
||||
return actionClassPrisma;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(`Database error when creating an action for environment ${environmentId}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
|
||||
import { AIRTABLE_CLIENT_ID } from "../constants";
|
||||
import { createOrUpdateIntegration, deleteIntegration, getIntegrationByType } from "../integration/service";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
interface ConnectAirtableOptions {
|
||||
environmentId: string;
|
||||
@@ -95,7 +96,7 @@ export const fetchAirtableAuthToken = async (formData: Record<string, any>) => {
|
||||
const parsedToken = ZIntegrationAirtableTokenSchema.safeParse(tokenRes);
|
||||
|
||||
if (!parsedToken.success) {
|
||||
console.error(parsedToken.error);
|
||||
logger.error(parsedToken.error);
|
||||
throw new Error(parsedToken.error.message);
|
||||
}
|
||||
const { access_token, refresh_token, expires_in } = parsedToken.data;
|
||||
@@ -255,6 +256,6 @@ export const writeData = async (
|
||||
}
|
||||
await addRecords(key, configData.baseId, configData.tableId, data);
|
||||
} catch (error: any) {
|
||||
console.error(error?.message);
|
||||
logger.error(error?.message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -31,6 +31,7 @@ import { createMembership } from "./membership/service";
|
||||
import { createProduct } from "./product/service";
|
||||
import { createTeam, getTeam } from "./team/service";
|
||||
import { createUser, getUserByEmail, updateUser } from "./user/service";
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
providers: [
|
||||
@@ -63,7 +64,7 @@ export const authOptions: NextAuthOptions = {
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
logger.error(e);
|
||||
throw Error("Internal server error. Please try again later");
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ export const authOptions: NextAuthOptions = {
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
logger.error(e);
|
||||
throw new Error("Either a user does not match the provided token or the token is invalid");
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import { TPerson } from "@formbricks/types/people";
|
||||
import { ITEMS_PER_PAGE, SERVICES_REVALIDATION_INTERVAL } from "../constants";
|
||||
import { createPerson, getPersonByUserId } from "../person/service";
|
||||
import { formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { displayCache } from "./cache";
|
||||
|
||||
@@ -111,7 +112,7 @@ export const updateDisplay = async (
|
||||
|
||||
return display;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
@@ -152,7 +153,7 @@ export const updateDisplayLegacy = async (
|
||||
|
||||
return display;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import { getProductByEnvironmentId } from "../product/service";
|
||||
import { getQuestionResponseMapping } from "../responses";
|
||||
import { getOriginalFileNameFromUrl } from "../storage/utils";
|
||||
import { getTeamByEnvironmentId } from "../team/service";
|
||||
import { logger } from "../utils/logger";
|
||||
import { withEmailTemplate } from "./email-template";
|
||||
|
||||
const nodemailer = require("nodemailer");
|
||||
@@ -65,7 +66,7 @@ export const sendEmail = async (emailData: sendEmailData) => {
|
||||
};
|
||||
await transporter.sendMail({ ...emailDefaults, ...emailData });
|
||||
} else {
|
||||
console.error(`Could not Email :: SMTP not configured :: ${emailData.subject}`);
|
||||
logger.error(`Could not Email :: SMTP not configured :: ${emailData.subject}`);
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
||||
@@ -22,6 +22,7 @@ import { SERVICES_REVALIDATION_INTERVAL } from "../constants";
|
||||
import { getProducts } from "../product/service";
|
||||
import { getTeamsByUserId } from "../team/service";
|
||||
import { formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { environmentCache } from "./cache";
|
||||
|
||||
@@ -39,7 +40,7 @@ export const getEnvironment = async (environmentId: string): Promise<TEnvironmen
|
||||
return environment;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ export const getEnvironments = async (productId: string): Promise<TEnvironment[]
|
||||
return environments;
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
console.error(JSON.stringify(error.errors, null, 2));
|
||||
logger.error(JSON.stringify(error.errors, null, 2));
|
||||
}
|
||||
throw new ValidationError("Data validation of environments array failed");
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
|
||||
import { ITEMS_PER_PAGE, SERVICES_REVALIDATION_INTERVAL } from "../constants";
|
||||
import { formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { integrationCache } from "./cache";
|
||||
|
||||
@@ -50,7 +51,7 @@ export async function createOrUpdateIntegration(
|
||||
return integration;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
throw error;
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ import jwt, { JwtPayload } from "jsonwebtoken";
|
||||
import { prisma } from "@formbricks/database";
|
||||
|
||||
import { env } from "./env";
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
export function createToken(userId: string, userEmail: string, options = {}): string {
|
||||
return jwt.sign({ id: userId }, env.NEXTAUTH_SECRET + userEmail, options);
|
||||
@@ -59,7 +60,7 @@ export const verifyInviteToken = (token: string): { inviteId: string; email: str
|
||||
email,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error verifying invite token:", error);
|
||||
logger.error(`Error verifying invite token: ${error}`);
|
||||
throw new Error("Invalid or expired invite token");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
|
||||
import { productCache } from "../product/cache";
|
||||
import { surveyCache } from "../survey/cache";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
|
||||
const languageSelect = {
|
||||
@@ -53,7 +54,7 @@ export const createLanguage = async (
|
||||
return language;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
throw error;
|
||||
@@ -81,7 +82,7 @@ export const getSurveysUsingGivenLanguage = async (languageId: string): Promise<
|
||||
return surveyNames;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
throw error;
|
||||
@@ -116,7 +117,7 @@ export const deleteLanguage = async (environmentId: string, languageId: string):
|
||||
return language;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
throw error;
|
||||
@@ -156,7 +157,7 @@ export const updateLanguage = async (
|
||||
return language;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
throw error;
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
"nanoid": "^5.0.6",
|
||||
"next-auth": "^4.24.7",
|
||||
"nodemailer": "^6.9.12",
|
||||
"pino": "^8.19.0",
|
||||
"pino-pretty": "^10.3.1",
|
||||
"posthog-node": "^3.6.3",
|
||||
"server-only": "^0.0.1",
|
||||
"tailwind-merge": "^2.2.1"
|
||||
|
||||
@@ -16,6 +16,7 @@ import { environmentCache } from "../environment/cache";
|
||||
import { createEnvironment } from "../environment/service";
|
||||
import { deleteLocalFilesByEnvironmentId, deleteS3FilesByEnvironmentId } from "../storage/service";
|
||||
import { formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { productCache } from "./cache";
|
||||
|
||||
@@ -90,7 +91,7 @@ export const getProductByEnvironmentId = async (environmentId: string): Promise<
|
||||
return productPrisma;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
throw error;
|
||||
@@ -149,7 +150,7 @@ export const updateProduct = async (
|
||||
return product;
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
console.error(JSON.stringify(error.errors, null, 2));
|
||||
logger.error(JSON.stringify(error.errors, null, 2));
|
||||
}
|
||||
throw new ValidationError("Data validation of product failed");
|
||||
}
|
||||
@@ -204,7 +205,7 @@ export const deleteProduct = async (productId: string): Promise<TProduct> => {
|
||||
await Promise.all(s3FilesPromises);
|
||||
} catch (err) {
|
||||
// fail silently because we don't want to throw an error if the files are not deleted
|
||||
console.error(err);
|
||||
logger.error(err);
|
||||
}
|
||||
} else {
|
||||
const localFilesPromises = product.environments.map(async (environment) => {
|
||||
@@ -215,7 +216,7 @@ export const deleteProduct = async (productId: string): Promise<TProduct> => {
|
||||
await Promise.all(localFilesPromises);
|
||||
} catch (err) {
|
||||
// fail silently because we don't want to throw an error if the files are not deleted
|
||||
console.error(err);
|
||||
logger.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import { TResponseNote, ZResponseNote } from "@formbricks/types/responses";
|
||||
import { SERVICES_REVALIDATION_INTERVAL } from "../constants";
|
||||
import { responseCache } from "../response/cache";
|
||||
import { formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { responseNoteCache } from "./cache";
|
||||
|
||||
@@ -64,7 +65,7 @@ export const createResponseNote = async (
|
||||
});
|
||||
return responseNote;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
@@ -85,7 +86,7 @@ export const getResponseNote = async (responseNoteId: string): Promise<TResponse
|
||||
});
|
||||
return responseNote;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
@@ -116,7 +117,7 @@ export const getResponseNotes = async (responseId: string): Promise<TResponseNot
|
||||
}
|
||||
return responseNotes;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
@@ -158,7 +159,7 @@ export const updateResponseNote = async (responseNoteId: string, text: string):
|
||||
|
||||
return updatedResponseNote;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
@@ -194,7 +195,7 @@ export const resolveResponseNote = async (responseNoteId: string): Promise<TResp
|
||||
|
||||
return responseNote;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { TResponseUpdate } from "@formbricks/types/responses";
|
||||
|
||||
import SurveyState from "./surveyState";
|
||||
import { delay } from "./utils";
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
interface QueueConfig {
|
||||
apiHost: string;
|
||||
@@ -55,14 +56,14 @@ export class ResponseQueue {
|
||||
this.queue.shift(); // remove the successfully sent response from the queue
|
||||
break; // exit the retry loop
|
||||
}
|
||||
console.error("Formbricks: Failed to send response. Retrying...", attempts);
|
||||
logger.error(`Formbricks: Failed to send response. Retrying... ${attempts}`);
|
||||
await delay(1000); // wait for 1 second before retrying
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (attempts >= this.config.retryAttempts) {
|
||||
// Inform the user after 2 failed attempts
|
||||
console.error("Failed to send response after 2 attempts.");
|
||||
logger.error("Failed to send response after 2 attempts.");
|
||||
// If the response fails finally, inform the user
|
||||
if (this.config.onResponseSendingFailed) {
|
||||
this.config.onResponseSendingFailed(responseUpdate);
|
||||
@@ -97,7 +98,7 @@ export class ResponseQueue {
|
||||
responseId: response.data.id,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update display, proceeding with the response.", error);
|
||||
logger.error(`Failed to update display, proceeding with the response. ${error}`);
|
||||
}
|
||||
}
|
||||
this.surveyState.updateResponseId(response.data.id);
|
||||
@@ -107,7 +108,7 @@ export class ResponseQueue {
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
} from "../constants";
|
||||
import { generateLocalSignedUrl } from "../crypto";
|
||||
import { env } from "../env";
|
||||
import { logger } from "../utils/logger";
|
||||
import { storageCache } from "./cache";
|
||||
|
||||
// S3Client Singleton
|
||||
@@ -66,7 +67,7 @@ export const testS3BucketAccess = async () => {
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("Failed to access S3 bucket:", error);
|
||||
logger.error(`Failed to access S3 bucket: ${error}`);
|
||||
throw new Error(`S3 Bucket Access Test Failed: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
export const getOriginalFileNameFromUrl = (fileURL: string) => {
|
||||
try {
|
||||
const fileNameFromURL = fileURL.startsWith("/storage/")
|
||||
@@ -16,6 +18,6 @@ export const getOriginalFileNameFromUrl = (fileURL: string) => {
|
||||
const fileName = originalFileName ? decodeURIComponent(`${originalFileName}.${fileExt}` || "") : "";
|
||||
return fileName;
|
||||
} catch (error) {
|
||||
console.error("Error parsing file URL:", error);
|
||||
logger.error(`Error parsing file URL: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@ import { createSegment, evaluateSegment, getSegment, updateSegment } from "../se
|
||||
import { transformSegmentFiltersToAttributeFilters } from "../segment/utils";
|
||||
import { subscribeTeamMembersToSurveyResponses } from "../team/service";
|
||||
import { diffInDays, formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { surveyCache } from "./cache";
|
||||
import { anySurveyHasFilters } from "./util";
|
||||
@@ -187,10 +188,9 @@ export const getSurvey = async (surveyId: string): Promise<TSurvey | null> => {
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ export const getSurveys = async (
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ export const getSurveyCount = async (environmentId: string): Promise<number> =>
|
||||
return surveyCount;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ export const updateSurvey = async (updatedSurvey: TSurvey): Promise<TSurvey> =>
|
||||
try {
|
||||
await updateSegment(segment.id, segment);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new Error("Error updating survey");
|
||||
}
|
||||
}
|
||||
@@ -512,7 +512,7 @@ export const updateSurvey = async (updatedSurvey: TSurvey): Promise<TSurvey> =>
|
||||
return modifiedSurvey;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import { environmentCache } from "../environment/cache";
|
||||
import { getProducts } from "../product/service";
|
||||
import { getUsersWithTeam, updateUser } from "../user/service";
|
||||
import { formatDateFields } from "../utils/datetime";
|
||||
import { logger } from "../utils/logger";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { teamCache } from "./cache";
|
||||
|
||||
@@ -100,7 +101,7 @@ export const getTeamByEnvironmentId = async (environmentId: string): Promise<TTe
|
||||
return team;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
and we cannot trace anything back to you or your customers. If you still want to
|
||||
disable telemetry, set the environment variable TELEMETRY_DISABLED=1 */
|
||||
import { env } from "./env";
|
||||
import { logger } from "./utils/logger";
|
||||
|
||||
export const captureTelemetry = async (eventName: string, properties = {}) => {
|
||||
if (env.TELEMETRY_DISABLED !== "1" && process.env.NODE_ENV === "production" && process.env.INSTANCE_ID) {
|
||||
@@ -21,7 +22,7 @@ export const captureTelemetry = async (eventName: string, properties = {}) => {
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("error sending telemetry:", error);
|
||||
logger.error(`error sending telemetry: ${error}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import z from "zod";
|
||||
|
||||
import { logger } from "./logger";
|
||||
|
||||
// Helper function to calculate difference in days between two dates
|
||||
export const diffInDays = (date1: Date, date2: Date) => {
|
||||
const diffTime = Math.abs(date2.getTime() - date1.getTime());
|
||||
@@ -35,7 +37,7 @@ export function formatDateFields<T extends z.ZodRawShape>(
|
||||
(formattedObject as any)[key] = new Date(dateStr);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error parsing date for key ${key}:`, error);
|
||||
logger.error(`Error parsing date for key ${key}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { AsyncParser } from "@json2csv/node";
|
||||
import * as xlsx from "xlsx";
|
||||
|
||||
import { logger } from "./logger";
|
||||
|
||||
export const convertToCsv = async (fields: string[], jsonData: Record<string, string | number>[]) => {
|
||||
let csv: string = "";
|
||||
|
||||
@@ -11,7 +13,7 @@ export const convertToCsv = async (fields: string[], jsonData: Record<string, st
|
||||
try {
|
||||
csv = await parser.parse(jsonData).promise();
|
||||
} catch (err) {
|
||||
console.log({ err });
|
||||
logger.error({ err });
|
||||
throw new Error("Failed to convert to CSV");
|
||||
}
|
||||
return csv;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import pino from "pino";
|
||||
|
||||
export const logger = pino({
|
||||
level: "info",
|
||||
timestamp: pino.stdTimeFunctions.isoTime,
|
||||
transport: {
|
||||
targets: [
|
||||
{
|
||||
level: "info",
|
||||
target: "pino-pretty",
|
||||
options: {
|
||||
colorize: true,
|
||||
levelFirst: true,
|
||||
translateTime: "yyyy-dd-mm, h:MM:ss TT",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
formatters: {
|
||||
bindings: () => ({}),
|
||||
},
|
||||
});
|
||||
@@ -2,6 +2,8 @@ import z from "zod";
|
||||
|
||||
import { ValidationError } from "@formbricks/types/errors";
|
||||
|
||||
import { logger } from "./logger";
|
||||
|
||||
type ValidationPair = [any, z.ZodSchema<any>];
|
||||
|
||||
export const validateInputs = (...pairs: ValidationPair[]): void => {
|
||||
@@ -9,7 +11,7 @@ export const validateInputs = (...pairs: ValidationPair[]): void => {
|
||||
const inputValidation = schema.safeParse(value);
|
||||
|
||||
if (!inputValidation.success) {
|
||||
console.error(
|
||||
logger.error(
|
||||
`Validation failed for ${JSON.stringify(value)} and ${JSON.stringify(schema)}: ${inputValidation.error.message}`
|
||||
);
|
||||
throw new ValidationError("Validation failed");
|
||||
|
||||
Reference in New Issue
Block a user