replace all the console logs with logger logs

This commit is contained in:
Hongbo Wu
2023-07-27 16:06:44 +08:00
parent 808f6f3d3a
commit 99a52f8d56
70 changed files with 452 additions and 382 deletions

View File

@ -4,30 +4,29 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/require-await */
import { makeExecutableSchema } from '@graphql-tools/schema'
import * as Sentry from '@sentry/node'
import { ContextFunction } from 'apollo-server-core'
import { ClaimsToSet, ResolverContext } from './resolvers/types'
import { SetClaimsRole } from './utils/dictionary'
import { Knex } from 'knex'
import { ApolloServer } from 'apollo-server-express'
import { ExpressContext } from 'apollo-server-express/dist/ApolloServer'
import * as jwt from 'jsonwebtoken'
import { kx } from './datalayer/knex_config'
import { tracer } from './tracing'
import { env } from './env'
import { Knex } from 'knex'
import { promisify } from 'util'
import { buildLogger } from './utils/logger'
import { ApolloServer } from 'apollo-server-express'
import { makeExecutableSchema } from '@graphql-tools/schema'
import typeDefs from './schema'
import { sanitizeDirectiveTransformer } from './directives'
import { functionResolvers } from './resolvers/function_resolvers'
import ScalarResolvers from './scalars'
import * as Sentry from '@sentry/node'
import { kx } from './datalayer/knex_config'
import { createPubSubClient } from './datalayer/pubsub'
import { sanitizeDirectiveTransformer } from './directives'
import { env } from './env'
import { functionResolvers } from './resolvers/function_resolvers'
import { ClaimsToSet, ResolverContext } from './resolvers/types'
import ScalarResolvers from './scalars'
import typeDefs from './schema'
import { initModels } from './server'
import { tracer } from './tracing'
import { getClaimsByToken, setAuthInCookie } from './utils/auth'
import { SetClaimsRole } from './utils/dictionary'
import { logger } from './utils/logger'
const signToken = promisify(jwt.sign)
const logger = buildLogger('app.dispatch')
const pubsub = createPubSubClient()
const resolvers = {

View File

@ -11,7 +11,7 @@ import { snakeCase } from 'snake-case'
import { buildLogger } from '../utils/logger'
import { SetClaimsRole } from '../utils/dictionary'
const logger = buildLogger('datalayer')
export const logger = buildLogger('datalayer')
export const setClaims = async (
tx: Knex.Transaction,

View File

@ -5,7 +5,7 @@ import DataModel, { DataModelError, MAX_RECORDS_LIMIT } from '../model'
import { CreateSet, HighlightData, keys as modelKeys, UpdateSet } from './model'
import { Table } from '../../utils/dictionary'
import { Knex } from 'knex'
import { ENABLE_DB_REQUEST_LOGGING, globalCounter } from '../helpers'
import { ENABLE_DB_REQUEST_LOGGING, globalCounter, logger } from '../helpers'
import DataLoader from 'dataloader'
class HighlightModel extends DataModel<HighlightData, CreateSet, UpdateSet> {
@ -40,11 +40,11 @@ class HighlightModel extends DataModel<HighlightData, CreateSet, UpdateSet> {
}
const result = keys.map((key) => keyMap[key])
if (result.length !== keys.length) {
console.error('DataModel error: count mismatch ', keys, result)
logger.error('DataModel error: count mismatch ', keys, result)
}
return result
} catch (e) {
console.error('DataModel error ', e)
logger.error('DataModel error ', e)
throw e
}
},

View File

@ -20,7 +20,12 @@ import {
SortOrder,
SortParams,
} from '../../generated/graphql'
import { ENABLE_DB_REQUEST_LOGGING, globalCounter, logMethod } from '../helpers'
import {
ENABLE_DB_REQUEST_LOGGING,
globalCounter,
logMethod,
logger,
} from '../helpers'
import DataLoader from 'dataloader'
import { ArticleData } from '../article/model'
import { InFilter, LabelFilter, ReadFilter } from '../../utils/search'
@ -147,11 +152,11 @@ class UserArticleModel extends DataModel<
// logger.debug('\n\n\n\n\nResult for userId_articleId_load', { keys, result });
if (result.length !== keys.length) {
console.error('DataModel error: count mismatch ', keys, result)
logger.error('DataModel error: count mismatch ', keys, result)
}
return result
} catch (e) {
console.error('DataModel error: ', e)
logger.error('DataModel error: ', e)
throw e
}
},
@ -201,11 +206,11 @@ class UserArticleModel extends DataModel<
// logger.debug('\n\n\n\n\nResult for userArticleId_stats_load', { keys, result });
if (result.length !== keys.length) {
console.error('DataModel error: count mismatch ', keys, result)
logger.error('DataModel error: count mismatch ', keys, result)
}
return result
} catch (e) {
console.error('DataModel error: ', e)
logger.error('DataModel error: ', e)
throw e
}
},

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import DataLoader from 'dataloader'
import { Knex } from 'knex'
import { ENABLE_DB_REQUEST_LOGGING, globalCounter } from './helpers'
import { ENABLE_DB_REQUEST_LOGGING, globalCounter, logger } from './helpers'
export enum DataModelError {
notFound = 'NOT_FOUND',
@ -46,11 +46,11 @@ abstract class DataModel<
}
const result = keys.map((key) => keyMap[key])
if (result.length !== keys.length) {
console.error('DataModel error: count mismatch ', keys, result)
logger.error('DataModel error: count mismatch ', keys, result)
}
return result
} catch (e) {
console.error('DataModel error: ', e)
logger.error('DataModel error: ', e)
throw e
}
},

View File

@ -12,7 +12,12 @@ import {
} from './model'
import DataModel, { DataModelError, MAX_RECORDS_LIMIT } from '../model'
import { Knex } from 'knex'
import { ENABLE_DB_REQUEST_LOGGING, globalCounter, logMethod } from '../helpers'
import {
ENABLE_DB_REQUEST_LOGGING,
globalCounter,
logMethod,
logger,
} from '../helpers'
import { Table } from '../../utils/dictionary'
import DataLoader from 'dataloader'
import { Partialize } from '../../util'
@ -57,11 +62,11 @@ class UserModel extends DataModel<UserData, CreateSet, UpdateSet> {
}
const result = keys.map((key) => keyMap[key])
if (result.length !== keys.length) {
console.error('DataModel error: count mismatch ', keys, result)
logger.error('DataModel error: count mismatch ', keys, result)
}
return result
} catch (e) {
console.error('DataModel error: ', e)
logger.error('DataModel error: ', e)
throw e
}
},

View File

@ -8,7 +8,12 @@ import {
import DataModel, { MAX_RECORDS_LIMIT } from '../model'
import { Knex } from 'knex'
import { Table } from '../../utils/dictionary'
import { ENABLE_DB_REQUEST_LOGGING, globalCounter, logMethod } from '../helpers'
import {
ENABLE_DB_REQUEST_LOGGING,
globalCounter,
logMethod,
logger,
} from '../helpers'
import DataLoader from 'dataloader'
class UserFriendModel extends DataModel<UserFriendData, CreateSet, UpdateSet> {
@ -43,7 +48,7 @@ class UserFriendModel extends DataModel<UserFriendData, CreateSet, UpdateSet> {
// logger.debug('\n\n\n\n\nResult for userId_articleId_load', { keys, result });
if (result.length !== keys.length) {
console.error('DataModel error: count mismatch ', keys, result)
logger.error('DataModel error: count mismatch ', keys, result)
}
return result
},

View File

@ -1,8 +1,7 @@
import { errors } from '@elastic/elasticsearch'
import { EntityType } from '../datalayer/pubsub'
import { buildLogger } from '../utils/logger'
import { SortBy, SortOrder, SortParams } from '../utils/search'
import { client, INDEX_ALIAS } from './index'
import { client, INDEX_ALIAS, logger } from './index'
import {
Highlight,
Page,
@ -12,8 +11,6 @@ import {
SearchResponse,
} from './types'
const logger = buildLogger('elasticsearch')
export const addHighlightToPage = async (
id: string,
highlight: Highlight,

View File

@ -1,6 +1,7 @@
import { env } from '../env'
import { Client } from '@elastic/elasticsearch'
import { readFileSync } from 'fs'
import { env } from '../env'
import { buildLogger } from '../utils/logger'
export const INDEX_ALIAS = 'pages_alias'
export const client = new Client({
@ -13,6 +14,7 @@ export const client = new Client({
},
})
const INDEX_NAME = 'pages'
export const logger = buildLogger('elasticsearch')
const createIndex = async (): Promise<void> => {
// read index settings from file
@ -31,22 +33,22 @@ const createIndex = async (): Promise<void> => {
export const initElasticsearch = async (): Promise<void> => {
try {
const response = await client.info()
console.log('elastic info: ', response)
logger.info('elastic info: ', response)
// check if index exists
const { body: indexExists } = await client.indices.exists({
index: INDEX_ALIAS,
})
if (!indexExists) {
console.log('creating index...')
logger.info('creating index...')
await createIndex()
console.log('refreshing index...')
logger.info('refreshing index...')
await refreshIndex()
}
console.log('elastic client is ready')
logger.info('elastic client is ready')
} catch (e) {
console.error('failed to init elasticsearch', e)
logger.error('failed to init elasticsearch', e)
throw e
}
}
@ -56,9 +58,9 @@ export const refreshIndex = async (): Promise<void> => {
const { body } = await client.indices.refresh({
index: INDEX_ALIAS,
})
console.log('elastic refresh: ', body)
logger.info('elastic refresh: ', body)
} catch (e) {
console.error('failed to refresh elastic index', e)
logger.error('failed to refresh elastic index', e)
throw e
}
}

View File

@ -1,11 +1,8 @@
import { errors } from '@elastic/elasticsearch'
import { EntityType } from '../datalayer/pubsub'
import { buildLogger } from '../utils/logger'
import { client, INDEX_ALIAS } from './index'
import { client, INDEX_ALIAS, logger } from './index'
import { Label, PageContext } from './types'
const logger = buildLogger('elasticsearch')
export const addLabelInPage = async (
pageId: string,
label: Label,

View File

@ -3,7 +3,6 @@ import { BuiltQuery, ESBuilder, esBuilder } from 'elastic-ts'
import { EntityType } from '../datalayer/pubsub'
import { BulkActionType } from '../generated/graphql'
import { wordsCount } from '../utils/helpers'
import { buildLogger } from '../utils/logger'
import {
DateFilter,
FieldFilter,
@ -16,7 +15,7 @@ import {
SortBy,
SortOrder,
} from '../utils/search'
import { client, INDEX_ALIAS } from './index'
import { client, INDEX_ALIAS, logger } from './index'
import {
ArticleSavingRequestStatus,
Label,
@ -28,8 +27,6 @@ import {
SearchResponse,
} from './types'
const logger = buildLogger('elasticsearch')
const appendQuery = (builder: ESBuilder, query: string): ESBuilder => {
interface Field {
field: string

View File

@ -1,4 +1,4 @@
import { buildLogger } from '../utils/logger'
import { logger } from '.'
import { createPage, getPageByParam, updatePage } from './pages'
import {
ArticleSavingRequestStatus,
@ -7,8 +7,6 @@ import {
Recommendation,
} from './types'
const logger = buildLogger('app.dispatch')
export const addRecommendation = async (
ctx: PageContext,
page: Page,

View File

@ -1,14 +1,13 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { PubSub } from '@google-cloud/pubsub'
import {
BaseEntity,
EntitySubscriberInterface,
EventSubscriber,
InsertEvent,
} from 'typeorm'
import { env } from '../env'
import { logger } from '../utils/logger'
const TOPIC_NAME = 'EntityCreated'
@ -24,7 +23,7 @@ export class PublishEntitySubscriber implements EntitySubscriberInterface {
})
if (env.dev.isLocal) {
console.log('PublishEntitySubscriber', msg)
logger.info('PublishEntitySubscriber', msg)
return
}
@ -32,7 +31,7 @@ export class PublishEntitySubscriber implements EntitySubscriberInterface {
.topic(TOPIC_NAME)
.publish(Buffer.from(msg))
.catch((err) => {
console.error('PublishEntitySubscriber error publishing event', err)
logger.error('PublishEntitySubscriber error publishing event', err)
})
}
}

View File

@ -4,9 +4,9 @@ import {
EventSubscriber,
InsertEvent,
} from 'typeorm'
import { ContentDisplayReport } from '../../entity/reports/content_display_report'
import { env } from '../../env'
import { logger } from '../../utils/logger'
import { sendEmail } from '../../utils/sendEmail'
@EventSubscriber()
@ -23,7 +23,7 @@ export class ContentDisplayReportSubscriber
${report.user.id} for URL: ${report.originalUrl}
${report.reportComment}`
console.log(message)
logger.info(message)
if (!env.dev.isLocal) {
// If we are in the local environment, just log a message, otherwise email the report

View File

@ -3,13 +3,13 @@ import {
EventSubscriber,
InsertEvent,
} from 'typeorm'
import { Profile } from '../../entity/profile'
import { IntercomClient } from '../../utils/intercom'
import { createPubSubClient } from '../../datalayer/pubsub'
import { Profile } from '../../entity/profile'
import { env } from '../../env'
import { analytics } from '../../utils/analytics'
import { addPopularReadsForNewUser } from '../../services/popular_reads'
import { analytics } from '../../utils/analytics'
import { IntercomClient } from '../../utils/intercom'
import { logger } from '../../utils/logger'
@EventSubscriber()
export class CreateIntercomAccount
@ -56,7 +56,7 @@ export class IdentifySegmentUser implements EntitySubscriberInterface<Profile> {
},
})
} catch (error) {
console.log('error in sign up', error)
logger.info('error in sign up', error)
}
return Promise.resolve()
}

View File

@ -19,6 +19,7 @@ import {
} from '../generated/graphql'
import { userDataToUser, validatedDate, wordsCount } from '../utils/helpers'
import { createImageProxyUrl } from '../utils/imageproxy'
import { logger } from '../utils/logger'
import {
contentReaderForPage,
generateDownloadSignedUrl,
@ -317,7 +318,7 @@ export const functionResolvers = {
if (a && a.image) {
a.image = createImageProxyUrl(a.image, 0, 180)
} else {
console.log(
logger.info(
'error getting article for feedItem',
feedArticle.userId,
feedArticle.articleId

View File

@ -1,27 +1,25 @@
import { authorized } from '../../utils/helpers'
import { DateTime } from 'luxon'
import { v4 as uuidv4 } from 'uuid'
import { User } from '../../entity/user'
import { getRepository } from '../../entity/utils'
import { env } from '../../env'
import {
UploadImportFileErrorCode,
MutationUploadImportFileArgs,
UploadImportFileError,
UploadImportFileErrorCode,
UploadImportFileSuccess,
} from '../../generated/graphql'
import { getRepository } from '../../entity/utils'
import { User } from '../../entity/user'
import { analytics } from '../../utils/analytics'
import { env } from '../../env'
import { DateTime } from 'luxon'
import { authorized } from '../../utils/helpers'
import { logger } from '../../utils/logger'
import {
countOfFilesWithPrefix,
generateUploadSignedUrl,
} from '../../utils/uploads'
import { v4 as uuidv4 } from 'uuid'
import { buildLogger } from '../../utils/logger'
const MAX_DAILY_UPLOADS = 4
const VALID_CONTENT_TYPES = ['text/csv', 'application/zip']
const logger = buildLogger('app.dispatch')
const extensionForContentType = (contentType: string) => {
switch (contentType) {
case 'text/csv':

View File

@ -18,15 +18,10 @@ export const updateLinkShareInfoResolver = authorized<
UpdateLinkShareInfoSuccess,
UpdateLinkShareInfoError,
MutationUpdateLinkShareInfoArgs
>(async (_obj, args, { models, claims, authTrx }) => {
>(async (_obj, args, { models, claims, authTrx, log }) => {
const { title, description } = args.input
console.log(
'updateLinkShareInfoResolver',
args.input.linkId,
title,
description
)
log.info('updateLinkShareInfoResolver', args.input.linkId, title, description)
// TEMP: because the old API uses articles instead of Links, we are actually
// getting an article ID here and need to map it to a link ID. When the API
@ -62,8 +57,8 @@ export const setLinkArchivedResolver = authorized<
ArchiveLinkSuccess,
ArchiveLinkError,
MutationSetLinkArchivedArgs
>(async (_obj, args, { claims, pubsub }) => {
console.log('setLinkArchivedResolver', args.input.linkId)
>(async (_obj, args, { claims, pubsub, log }) => {
log.info('setLinkArchivedResolver', args.input.linkId)
analytics.track({
userId: claims.uid,

View File

@ -1,4 +1,7 @@
import { authorized } from '../../utils/helpers'
import { NewsletterEmail } from '../../entity/newsletter_email'
import { User } from '../../entity/user'
import { getRepository } from '../../entity/utils'
import { env } from '../../env'
import {
CreateNewsletterEmailError,
CreateNewsletterEmailErrorCode,
@ -16,18 +19,15 @@ import {
deleteNewsletterEmail,
getNewsletterEmails,
} from '../../services/newsletters'
import { NewsletterEmail } from '../../entity/newsletter_email'
import { analytics } from '../../utils/analytics'
import { env } from '../../env'
import { User } from '../../entity/user'
import { unsubscribeAll } from '../../services/subscriptions'
import { getRepository } from '../../entity/utils'
import { analytics } from '../../utils/analytics'
import { authorized } from '../../utils/helpers'
export const createNewsletterEmailResolver = authorized<
CreateNewsletterEmailSuccess,
CreateNewsletterEmailError
>(async (_parent, _args, { claims }) => {
console.log('createNewsletterEmailResolver')
>(async (_parent, _args, { claims, log }) => {
log.info('createNewsletterEmailResolver')
analytics.track({
userId: claims.uid,
event: 'newsletter_email_address_created',
@ -46,7 +46,7 @@ export const createNewsletterEmailResolver = authorized<
},
}
} catch (e) {
console.log(e)
log.info(e)
return {
errorCodes: [CreateNewsletterEmailErrorCode.BadRequest],
@ -57,8 +57,8 @@ export const createNewsletterEmailResolver = authorized<
export const newsletterEmailsResolver = authorized<
NewsletterEmailsSuccess,
NewsletterEmailsError
>(async (_parent, _args, { claims }) => {
console.log('newsletterEmailsResolver')
>(async (_parent, _args, { claims, log }) => {
log.info('newsletterEmailsResolver')
try {
const user = await getRepository(User).findOneBy({
@ -79,7 +79,7 @@ export const newsletterEmailsResolver = authorized<
})),
}
} catch (e) {
console.log(e)
log.info(e)
return {
errorCodes: [NewsletterEmailsErrorCode.BadRequest],
@ -91,8 +91,8 @@ export const deleteNewsletterEmailResolver = authorized<
DeleteNewsletterEmailSuccess,
DeleteNewsletterEmailError,
MutationDeleteNewsletterEmailArgs
>(async (_parent, args, { claims }) => {
console.log('deleteNewsletterEmailResolver')
>(async (_parent, args, { claims, log }) => {
log.info('deleteNewsletterEmailResolver')
analytics.track({
userId: claims.uid,
event: 'newsletter_email_address_deleted',
@ -139,7 +139,7 @@ export const deleteNewsletterEmailResolver = authorized<
}
}
} catch (e) {
console.log(e)
log.info(e)
return {
errorCodes: [DeleteNewsletterEmailErrorCode.BadRequest],

View File

@ -1,14 +1,14 @@
import { Merge } from '../../util'
import { authorized } from '../../utils/helpers'
import {
CreateReactionSuccess,
CreateReactionError,
MutationCreateReactionArgs,
CreateReactionErrorCode,
Reaction,
DeleteReactionErrorCode,
CreateReactionSuccess,
DeleteReactionError,
DeleteReactionErrorCode,
MutationCreateReactionArgs,
MutationDeleteReactionArgs,
Reaction,
} from './../../generated/graphql'
export type PartialReaction = Omit<Reaction, 'user'>
@ -93,7 +93,7 @@ export const createReactionResolver = authorized<
reaction: reaction as PartialReaction,
}
} catch (err) {
console.log(err)
log.info(err)
return {
errorCodes: [CreateReactionErrorCode.NotFound],
}

View File

@ -24,6 +24,7 @@ import { setLinkArchived } from '../../services/archive_link'
import { analytics } from '../../utils/analytics'
import { deleteTask, enqueueReminder } from '../../utils/createTask'
import { authorized } from '../../utils/helpers'
import { logger } from '../../utils/logger'
import { DataModels } from '../types'
const validScheduleTime = (str: string): Date | undefined => {
@ -99,7 +100,7 @@ export const createReminderResolver = authorized<
}
const taskName = await groupReminders(scheduledTime, uid, models)
console.log('scheduled task name', taskName)
log.info('scheduled task name', taskName)
// insert reminder to db
const reminder = await models.reminder.create({
@ -111,7 +112,7 @@ export const createReminderResolver = authorized<
remindAt: scheduledTime,
elasticPageId: pageId,
})
console.log('created reminder', reminder)
log.info('created reminder', reminder)
return {
reminder: {
@ -122,7 +123,7 @@ export const createReminderResolver = authorized<
},
}
} catch (e) {
console.log('error creating reminder', e)
log.info('error creating reminder', e)
return {
errorCodes: [CreateReminderErrorCode.BadRequest],
@ -138,7 +139,7 @@ const archivePage = async (uid: string, page: Page) => {
try {
await setLinkArchived(uid, page.id, true)
} catch (e) {
console.log('error archiving link', e)
logger.info('error archiving link', e)
}
}

View File

@ -1,13 +1,13 @@
import { User } from '../../entity/user'
import { env } from '../../env'
import {
SendInstallInstructionsError,
SendInstallInstructionsErrorCode,
SendInstallInstructionsSuccess,
} from '../../generated/graphql'
import { AppDataSource } from '../../server'
import { authorized } from '../../utils/helpers'
import { sendEmail } from '../../utils/sendEmail'
import { AppDataSource } from '../../server'
import { User } from '../../entity/user'
import { env } from '../../env'
const INSTALL_INSTRUCTIONS_EMAIL_TEMPLATE_ID =
'd-c576bdc3b9a849dab250655ba14c7794'
@ -15,7 +15,7 @@ const INSTALL_INSTRUCTIONS_EMAIL_TEMPLATE_ID =
export const sendInstallInstructionsResolver = authorized<
SendInstallInstructionsSuccess,
SendInstallInstructionsError
>(async (_parent, _args, { claims }) => {
>(async (_parent, _args, { claims, log }) => {
try {
const user = await AppDataSource.getRepository(User).findOneBy({
id: claims.uid,
@ -37,7 +37,7 @@ export const sendInstallInstructionsResolver = authorized<
sent: sendInstallInstructions,
}
} catch (e) {
console.log(e)
log.info(e)
return {
errorCodes: [SendInstallInstructionsErrorCode.BadRequest],

View File

@ -1,3 +1,8 @@
import * as jwt from 'jsonwebtoken'
import { deletePagesByParam } from '../../elastic/pages'
import { User as UserEntity } from '../../entity/user'
import { setClaims } from '../../entity/utils'
import { env } from '../../env'
import {
DeleteAccountError,
DeleteAccountErrorCode,
@ -28,16 +33,11 @@ import {
UsersError,
UsersSuccess,
} from '../../generated/graphql'
import { WithDataSourcesContext } from '../types'
import { authorized, userDataToUser } from '../../utils/helpers'
import { env } from '../../env'
import { validateUsername } from '../../utils/usernamePolicy'
import * as jwt from 'jsonwebtoken'
import { createUser } from '../../services/create_user'
import { deletePagesByParam } from '../../elastic/pages'
import { setClaims } from '../../entity/utils'
import { User as UserEntity } from '../../entity/user'
import { AppDataSource } from '../../server'
import { createUser } from '../../services/create_user'
import { authorized, userDataToUser } from '../../utils/helpers'
import { validateUsername } from '../../utils/usernamePolicy'
import { WithDataSourcesContext } from '../types'
export const updateUserResolver = authorized<
UpdateUserSuccess,
@ -184,7 +184,7 @@ export const googleSignupResolver: ResolverFn<
Record<string, unknown>,
WithDataSourcesContext,
MutationGoogleSignupArgs
> = async (_obj, { input }, { setAuth }) => {
> = async (_obj, { input }, { setAuth, log }) => {
const { email, username, name, bio, sourceUserId, pictureUrl, secret } = input
const lowerCasedUsername = username.toLowerCase()
@ -211,7 +211,7 @@ export const googleSignupResolver: ResolverFn<
me: userDataToUser({ ...user, profile: { ...profile, private: false } }),
}
} catch (err) {
console.log('error signing up with google', err)
log.info('error signing up with google', err)
if (isErrorWithCode(err)) {
return { errorCodes: [err.errorCode as SignupErrorCode] }
}
@ -224,12 +224,12 @@ export const logOutResolver: ResolverFn<
unknown,
WithDataSourcesContext,
unknown
> = (_, __, { clearAuth }) => {
> = (_, __, { clearAuth, log }) => {
try {
clearAuth()
return { message: 'User successfully logged out' }
} catch (error) {
console.error(error)
log.error(error)
return { errorCodes: [LogOutErrorCode.LogOutFailed] }
}
}

View File

@ -1,4 +1,7 @@
import { authorized } from '../../utils/helpers'
import { DatabaseError } from 'pg'
import { QueryFailedError } from 'typeorm'
import { UserDeviceToken } from '../../entity/user_device_tokens'
import { env } from '../../env'
import {
DeviceToken,
DeviceTokensError,
@ -9,8 +12,6 @@ import {
SetDeviceTokenErrorCode,
SetDeviceTokenSuccess,
} from '../../generated/graphql'
import { analytics } from '../../utils/analytics'
import { env } from '../../env'
import {
createDeviceToken,
deleteDeviceToken,
@ -18,9 +19,8 @@ import {
getDeviceTokenByToken,
getDeviceTokensByUserId,
} from '../../services/user_device_tokens'
import { UserDeviceToken } from '../../entity/user_device_tokens'
import { QueryFailedError } from 'typeorm'
import { DatabaseError } from 'pg'
import { analytics } from '../../utils/analytics'
import { authorized } from '../../utils/helpers'
const PG_UNIQUE_CONSTRAINT_VIOLATION = '23505'
@ -29,12 +29,12 @@ export const setDeviceTokenResolver = authorized<
SetDeviceTokenError,
MutationSetDeviceTokenArgs
>(async (_parent, { input }, { claims: { uid }, log }) => {
console.log('setDeviceTokenResolver', input)
log.info('setDeviceTokenResolver', input)
const { id, token } = input
if (!id && !token) {
console.log('id or token is required')
log.info('id or token is required')
return {
errorCodes: [SetDeviceTokenErrorCode.BadRequest],
@ -140,7 +140,7 @@ export const deviceTokensResolver = authorized<
})
const deviceTokens = await getDeviceTokensByUserId(uid)
console.log('deviceTokens', deviceTokens)
log.info('deviceTokens', deviceTokens)
return {
deviceTokens: deviceTokens.map(deviceTokenToData),

View File

@ -16,7 +16,7 @@ import { getClaimsByToken } from '../utils/auth'
import { isSiteBlockedForParse } from '../utils/blocked'
import { corsConfig } from '../utils/corsConfig'
import { enqueueTextToSpeech } from '../utils/createTask'
import { buildLogger } from '../utils/logger'
import { logger } from '../utils/logger'
import { generateDownloadSignedUrl } from '../utils/uploads'
interface SpeechInput {
@ -26,7 +26,6 @@ interface SpeechInput {
language?: string
}
const outputFormats = ['mp3', 'speech-marks', 'speech']
const logger = buildLogger('app.dispatch')
export function articleRouter() {
const router = express.Router()

View File

@ -3,16 +3,17 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import * as jwt from 'jsonwebtoken'
import jwksClient from 'jwks-rsa'
import UserModel from '../../datalayer/user'
import { env, homePageURL } from '../../env'
import { LoginErrorCode } from '../../generated/graphql'
import { logger } from '../../utils/logger'
import { createSsoToken, ssoRedirectURL } from '../../utils/sso'
import { DecodeTokenResult } from './auth_types'
import {
createWebAuthToken,
createPendingUserToken,
createWebAuthToken,
suggestedUsername,
} from './jwt_helpers'
import { env, homePageURL } from '../../env'
import UserModel from '../../datalayer/user'
import { LoginErrorCode } from '../../generated/graphql'
import { createSsoToken, ssoRedirectURL } from '../../utils/sso'
const appleBaseURL = 'https://appleid.apple.com'
const audienceName = 'app.omnivore.app'
@ -35,7 +36,7 @@ async function fetchApplePublicKey(kid: string): Promise<string | null> {
})
return key.getPublicKey()
} catch (e) {
console.log('fetchApplePublicKey error', e)
logger.error('fetchApplePublicKey error', e)
return null
}
}
@ -67,7 +68,7 @@ export async function decodeAppleToken(
}
}
} catch (e) {
console.log('decodeAppleToken error', e)
logger.error('decodeAppleToken error', e)
return { errorCode: 500 }
}
}
@ -152,7 +153,7 @@ export async function handleAppleWebAuth(
return { redirectURL: authFailedRedirect }
}
} catch (e) {
console.log('handleAppleWebAuth error', e)
logger.info('handleAppleWebAuth error', e)
return { redirectURL: authFailedRedirect }
}
}

View File

@ -7,52 +7,50 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import {
generateGoogleLoginURL,
googleAuth,
handleGoogleWebAuth,
validateGoogleUser,
} from './google_auth'
import axios from 'axios'
import cors from 'cors'
import type { Request, Response } from 'express'
import express from 'express'
import axios from 'axios'
import { env } from '../../env'
import * as jwt from 'jsonwebtoken'
import url from 'url'
import { promisify } from 'util'
import { kx } from '../../datalayer/knex_config'
import UserModel from '../../datalayer/user'
import { buildLogger } from '../../utils/logger'
import { promisify } from 'util'
import * as jwt from 'jsonwebtoken'
import { LoginErrorCode, SignupErrorCode } from '../../generated/graphql'
import { handleAppleWebAuth } from './apple_auth'
import type { AuthProvider } from './auth_types'
import { createMobileAccountCreationResponse } from './mobile/account_creation'
import { corsConfig } from '../../utils/corsConfig'
import cors from 'cors'
import {
RegistrationType,
StatusType,
UserData,
} from '../../datalayer/user/model'
import { User } from '../../entity/user'
import { getRepository, setClaims } from '../../entity/utils'
import { env } from '../../env'
import { LoginErrorCode, SignupErrorCode } from '../../generated/graphql'
import { isErrorWithCode } from '../../resolvers'
import { AppDataSource } from '../../server'
import { createUser, getUserByEmail } from '../../services/create_user'
import {
sendConfirmationEmail,
sendPasswordResetEmail,
} from '../../services/send_emails'
import {
comparePassword,
getClaimsByToken,
hashPassword,
setAuthInCookie,
} from '../../utils/auth'
import { createUser, getUserByEmail } from '../../services/create_user'
import { isErrorWithCode } from '../../resolvers'
import { AppDataSource } from '../../server'
import { getRepository, setClaims } from '../../entity/utils'
import { User } from '../../entity/user'
import {
sendConfirmationEmail,
sendPasswordResetEmail,
} from '../../services/send_emails'
import { createWebAuthToken } from './jwt_helpers'
import { corsConfig } from '../../utils/corsConfig'
import { logger } from '../../utils/logger'
import { createSsoToken, ssoRedirectURL } from '../../utils/sso'
import { handleAppleWebAuth } from './apple_auth'
import type { AuthProvider } from './auth_types'
import {
generateGoogleLoginURL,
googleAuth,
handleGoogleWebAuth,
validateGoogleUser,
} from './google_auth'
import { createWebAuthToken } from './jwt_helpers'
import { createMobileAccountCreationResponse } from './mobile/account_creation'
export interface SignupRequest {
email: string
@ -63,7 +61,6 @@ export interface SignupRequest {
pictureUrl?: string
}
const logger = buildLogger('app.dispatch')
const signToken = promisify(jwt.sign)
const cookieParams = {
@ -345,7 +342,7 @@ export function authRouter() {
const state = JSON.parse((req.query?.state || '') as string)
redirectUri = state?.redirect_uri
} catch (err) {
console.warn(
logger.warn(
'handleSuccessfulLogin: failed to parse redirect query state param',
err
)

View File

@ -1,12 +1,13 @@
import { google, oauth2_v2 as oauthV2 } from 'googleapis'
import url from 'url'
import { env, homePageURL } from '../../env'
import { OAuth2Client } from 'googleapis-common'
import { DecodeTokenResult } from './auth_types'
import { LoginErrorCode } from '../../generated/graphql'
import url from 'url'
import UserModel from '../../datalayer/user'
import { createWebAuthToken, createPendingUserToken } from './jwt_helpers'
import { ssoRedirectURL, createSsoToken } from '../../utils/sso'
import { env, homePageURL } from '../../env'
import { LoginErrorCode } from '../../generated/graphql'
import { logger } from '../../utils/logger'
import { createSsoToken, ssoRedirectURL } from '../../utils/sso'
import { DecodeTokenResult } from './auth_types'
import { createPendingUserToken, createWebAuthToken } from './jwt_helpers'
export const googleAuthMobile = (): OAuth2Client =>
new google.auth.OAuth2(env.google.auth.clientId, env.google.auth.secret)
@ -80,7 +81,7 @@ export async function decodeGoogleToken(
const sourceUserId = loginTicket.getUserId() || undefined
return { email, sourceUserId }
} catch (e) {
console.log('decodeGoogleToken error', e)
logger.info('decodeGoogleToken error', e)
return { errorCode: 500 }
}
}
@ -134,7 +135,7 @@ export async function handleGoogleWebAuth(
const userId = user?.id
if (!userId || !user?.profile) {
console.log(
logger.info(
'user or profile does not exist:',
sourceUserId,
'GOOGLE',
@ -171,7 +172,7 @@ export async function handleGoogleWebAuth(
return { redirectURL: authFailedRedirect }
}
} catch (e) {
console.log('handleGoogleWebAuth error', e)
logger.info('handleGoogleWebAuth error', e)
return { redirectURL: authFailedRedirect }
}
}

View File

@ -1,10 +1,11 @@
import * as cookie from 'cookie'
import * as jwt from 'jsonwebtoken'
import { promisify } from 'util'
import * as cookie from 'cookie'
import { env } from '../../env'
import { logger } from '../../utils/logger'
import {
PendingUserTokenPayload,
isPendingUserTokenPayload,
PendingUserTokenPayload,
} from './auth_types'
const signToken = promisify(jwt.sign)
@ -45,7 +46,7 @@ export async function createPendingUserToken(
): Promise<string | undefined> {
try {
const authToken = await signToken(payload, env.server.jwtSecret)
console.log('creating pending user auth token', payload)
logger.info('creating pending user auth token', payload)
if (typeof authToken === 'string') {
return authToken
} else {

View File

@ -4,6 +4,7 @@ import { StatusType } from '../../../datalayer/user/model'
import { getUserByEmail } from '../../../services/create_user'
import { sendConfirmationEmail } from '../../../services/send_emails'
import { comparePassword } from '../../../utils/auth'
import { logger } from '../../../utils/logger'
import { decodeAppleToken } from '../apple_auth'
import {
AuthProvider,
@ -31,7 +32,7 @@ export async function createMobileSignInResponse(
throw new Error(`Missing or unsupported provider ${provider}`)
} catch (e) {
console.log('createMobileSignInResponse error', e)
logger.error('createMobileSignInResponse error', e)
return authFailedPayload
}
}
@ -74,7 +75,7 @@ export async function createMobileEmailSignInResponse(
json: mobileAuthPayload,
}
} catch (e) {
console.log('createMobileEmailSignInResponse failed for user', {
logger.error('createMobileEmailSignInResponse failed for user', {
email,
error: e,
})
@ -117,7 +118,7 @@ async function createAuthResponsePayload(
json: mobileAuthPayload,
}
} catch (e) {
console.log('createAuthResponsePayload error', {
logger.error('createAuthResponsePayload error', {
error: e,
email: decodedTokenResult.email,
})

View File

@ -1,17 +1,18 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import UserModel from '../../../datalayer/user'
import { createUser } from '../../../services/create_user'
import { hashPassword } from '../../../utils/auth'
import { logger } from '../../../utils/logger'
import { decodeAppleToken } from '../apple_auth'
import { decodeGoogleToken } from '../google_auth'
import { isValidSignupRequest } from '../auth_router'
import {
AuthProvider,
DecodeTokenResult,
JsonResponsePayload,
AuthProvider,
PendingUserTokenPayload,
} from '../auth_types'
import { decodeGoogleToken } from '../google_auth'
import { createPendingUserToken, suggestedUsername } from '../jwt_helpers'
import UserModel from '../../../datalayer/user'
import { hashPassword } from '../../../utils/auth'
import { createUser } from '../../../services/create_user'
import { isValidSignupRequest } from '../auth_router'
export async function createMobileSignUpResponse(
isAndroid: boolean,
@ -40,7 +41,7 @@ export async function createMobileSignUpResponse(
throw new Error(`Missing or unsupported provider ${provider}`)
} catch (e) {
console.log('createMobileSignUpResponse error', e)
logger.info('createMobileSignUpResponse error', e)
return signUpFailedPayload
}
}
@ -73,7 +74,7 @@ export async function createMobileEmailSignUpResponse(
json: {},
}
} catch (e) {
console.log('error creating mobile email sign up response', e)
logger.info('error creating mobile email sign up response', e)
return signUpFailedPayload
}
}
@ -131,7 +132,7 @@ async function createSignUpResponsePayload(
json: { pendingUserToken, pendingUserProfile },
}
} catch (e) {
console.log('createSignUpResponsePayload error', e)
logger.info('createSignUpResponsePayload error', e)
return signUpFailedPayload
}
}

View File

@ -4,9 +4,7 @@ import express from 'express'
import { env } from '../env'
import { getClaimsByToken } from '../utils/auth'
import { corsConfig } from '../utils/corsConfig'
import { buildLogger } from '../utils/logger'
const logger = buildLogger('app.dispatch')
import { logger } from '../utils/logger'
export function integrationRouter() {
const router = express.Router()
@ -45,8 +43,13 @@ export function integrationRouter() {
res.redirect(
`https://getpocket.com/auth/authorize?request_token=${code}&redirect_uri=${redirectUri}?pocketToken=${code}`
)
} catch (e) {
logger.info('pocket/request-token exception:', e)
} catch (error) {
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error('pocket/request-token exception:', error)
}
res.redirect(
`${env.client.url}/settings/integrations?errorCodes=UNKNOWN`
)

View File

@ -27,14 +27,12 @@ import {
titleForFilePath,
validateUuid,
} from '../utils/helpers'
import { buildLogger } from '../utils/logger'
import { logger } from '../utils/logger'
import {
generateUploadFilePathName,
generateUploadSignedUrl,
} from '../utils/uploads'
const logger = buildLogger('app.dispatch')
export function pageRouter() {
const router = express.Router()

View File

@ -12,9 +12,7 @@ import { getPageByParam, updatePage } from '../../elastic/pages'
import { Page } from '../../elastic/types'
import { ArticleSavingRequestStatus } from '../../generated/graphql'
import { initModels } from '../../server'
import { buildLogger } from '../../utils/logger'
const logger = buildLogger('app.dispatch')
import { logger } from '../../utils/logger'
interface UpdateContentMessage {
fileId: string

View File

@ -12,7 +12,7 @@ import { updateReceivedEmail } from '../../services/received_emails'
import { analytics } from '../../utils/analytics'
import { getClaimsByToken } from '../../utils/auth'
import { generateSlug } from '../../utils/helpers'
import { buildLogger } from '../../utils/logger'
import { logger } from '../../utils/logger'
import {
generateUploadFilePathName,
generateUploadSignedUrl,
@ -20,8 +20,6 @@ import {
makeStorageFilePublic,
} from '../../utils/uploads'
const logger = buildLogger('app.dispatch')
export function emailAttachmentRouter() {
const router = express.Router()

View File

@ -1,27 +1,27 @@
import cors from 'cors'
import express from 'express'
import {
createPubSubClient,
readPushSubscription,
} from '../../datalayer/pubsub'
import { sendEmail } from '../../utils/sendEmail'
import { analytics } from '../../utils/analytics'
import { getNewsletterEmail } from '../../services/newsletters'
import { env } from '../../env'
import { getNewsletterEmail } from '../../services/newsletters'
import {
saveReceivedEmail,
updateReceivedEmail,
} from '../../services/received_emails'
import { saveEmail } from '../../services/save_email'
import { analytics } from '../../utils/analytics'
import { getClaimsByToken } from '../../utils/auth'
import { corsConfig } from '../../utils/corsConfig'
import { logger } from '../../utils/logger'
import {
generateUniqueUrl,
getTitleFromEmailSubject,
isProbablyArticle,
parseEmailAddress,
} from '../../utils/parser'
import { saveEmail } from '../../services/save_email'
import { buildLogger } from '../../utils/logger'
import {
saveReceivedEmail,
updateReceivedEmail,
} from '../../services/received_emails'
import cors from 'cors'
import { corsConfig } from '../../utils/corsConfig'
import { getClaimsByToken } from '../../utils/auth'
import { sendEmail } from '../../utils/sendEmail'
interface EmailMessage {
from: string
@ -39,8 +39,6 @@ function isEmailMessage(data: any): data is EmailMessage {
return 'from' in data && 'to' in data
}
const logger = buildLogger('app.dispatch')
export function emailsServiceRouter() {
const router = express.Router()

View File

@ -13,7 +13,7 @@ import { getRepository } from '../../entity/utils'
import { Claims } from '../../resolvers/types'
import { getIntegrationService } from '../../services/integrations'
import { getClaimsByToken } from '../../utils/auth'
import { buildLogger } from '../../utils/logger'
import { logger } from '../../utils/logger'
import { DateFilter } from '../../utils/search'
import { createGCSFile } from '../../utils/uploads'
@ -32,8 +32,6 @@ interface ImportEvent {
const isImportEvent = (event: any): event is ImportEvent =>
'integrationId' in event
const logger = buildLogger('app.dispatch')
export function integrationsServiceRouter() {
const router = express.Router()

View File

@ -4,6 +4,7 @@
import express from 'express'
import { readPushSubscription } from '../../datalayer/pubsub'
import { createPageSaveRequest } from '../../services/create_page_save_request'
import { logger } from '../../utils/logger'
interface CreateLinkRequestMessage {
url: string
@ -14,9 +15,9 @@ export function linkServiceRouter() {
const router = express.Router()
router.post('/create', async (req, res) => {
console.log('create link req', req.query, req.body)
logger.info('create link req', req.query, req.body)
const { message: msgStr, expired } = readPushSubscription(req)
console.log('read pubsub message', msgStr, 'has expired', expired)
logger.info('read pubsub message', msgStr, 'has expired', expired)
if (!msgStr) {
res.status(400).send('Bad Request')
@ -24,14 +25,14 @@ export function linkServiceRouter() {
}
if (expired) {
console.log('discarding expired message')
logger.info('discarding expired message')
res.status(200).send('Expired')
return
}
const data = JSON.parse(msgStr)
if (!('url' in data) || !('userId' in data)) {
console.log('No file url or userId found in message')
logger.info('No file url or userId found in message')
res.status(400).send('Bad Request')
return
}
@ -42,11 +43,11 @@ export function linkServiceRouter() {
userId: msg.userId,
url: msg.url,
})
console.log('create link request', request)
logger.info('create link request', request)
res.status(200).send(request)
} catch (err) {
console.log('create link failed', err)
logger.info('create link failed', err)
res.status(500).send(err)
}
})

View File

@ -16,9 +16,7 @@ import {
import { saveUrlFromEmail } from '../../services/save_url'
import { getSubscriptionByNameAndUserId } from '../../services/subscriptions'
import { isUrl } from '../../utils/helpers'
import { buildLogger } from '../../utils/logger'
const logger = buildLogger('app.dispatch')
import { logger } from '../../utils/logger'
interface SetConfirmationCodeMessage {
emailAddress: string

View File

@ -12,6 +12,7 @@ import { initModels } from '../../server'
import { getPagesWithReminder, PageReminder } from '../../services/reminders'
import { getDeviceTokensByUserId } from '../../services/user_device_tokens'
import { analytics } from '../../utils/analytics'
import { logger } from '../../utils/logger'
import { sendEmail } from '../../utils/sendEmail'
import { sendMulticastPushNotifications } from '../../utils/sendNotification'
@ -28,7 +29,7 @@ export function remindersServiceRouter() {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
router.post('/trigger', async (req, res) => {
console.log('reminders/trigger')
logger.info('reminders/trigger')
const { userId, scheduleTime } = req.body as {
userId?: string
@ -56,7 +57,7 @@ export function remindersServiceRouter() {
const user = await models.user.get(userId)
if (!user || !user.email) {
console.log('user not found', userId)
logger.info('user not found', userId)
res.status(400).send('User Not Found')
return
}
@ -64,12 +65,12 @@ export function remindersServiceRouter() {
const pageReminders = await getPagesWithReminder(userId, remindAt)
if (!pageReminders) {
console.log('pages with reminders not found', userId, scheduleTime)
logger.info('pages with reminders not found', userId, scheduleTime)
res.status(200).send('Reminders Not Found')
return
}
console.log('page with reminders:', pageReminders)
logger.info('page with reminders:', pageReminders)
const [pagesToNotify, pagesToUnarchive] = getPagesToNotifyAndUnarchive(
pageReminders,
@ -81,7 +82,7 @@ export function remindersServiceRouter() {
if (pagesToNotify.length > 0) {
// we have configured Sendgrid to send a template
if (!process.env.SENDGRID_REMINDER_TEMPLATE_ID) {
console.log('Sendgrid reminder email template_id not set')
logger.info('Sendgrid reminder email template_id not set')
await updateRemindersStatus(
models,
@ -99,7 +100,7 @@ export function remindersServiceRouter() {
articles: pagesToNotify,
}
console.log('dynamic template data:', dynamicTemplateData)
logger.info('dynamic template data:', dynamicTemplateData)
await sendEmail({
from: env.sender.message,
@ -116,7 +117,7 @@ export function remindersServiceRouter() {
}
if (!deviceTokens) {
console.log('Device tokens not set:', userId)
logger.info('Device tokens not set:', userId)
res.status(400).send('Device token Not Found')
return
@ -126,7 +127,7 @@ export function remindersServiceRouter() {
await updateRemindersStatus(models, userId, pagesToUnarchive, remindAt)
res.status(200).send('Reminders triggered')
} catch (e) {
console.log(e)
logger.info(e)
res.status(500).send(e)
}
})

View File

@ -5,9 +5,7 @@ import { Subscription } from '../../entity/subscription'
import { getRepository } from '../../entity/utils'
import { SubscriptionStatus, SubscriptionType } from '../../generated/graphql'
import { enqueueRssFeedFetch } from '../../utils/createTask'
import { buildLogger } from '../../utils/logger'
const logger = buildLogger('app.dispatch')
import { logger } from '../../utils/logger'
export function rssFeedRouter() {
const router = express.Router()

View File

@ -2,14 +2,12 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import express from 'express'
import { readPushSubscription } from '../../datalayer/pubsub'
import { uploadToBucket } from '../../utils/uploads'
import { v4 as uuidv4 } from 'uuid'
import { env } from '../../env'
import { DateTime } from 'luxon'
import { buildLogger } from '../../utils/logger'
const logger = buildLogger('app.dispatch')
import { v4 as uuidv4 } from 'uuid'
import { readPushSubscription } from '../../datalayer/pubsub'
import { env } from '../../env'
import { logger } from '../../utils/logger'
import { uploadToBucket } from '../../utils/uploads'
export function uploadServiceRouter() {
const router = express.Router()

View File

@ -1,14 +1,12 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import axios, { Method } from 'axios'
import express from 'express'
import { readPushSubscription } from '../../datalayer/pubsub'
import { getRepository } from '../../entity/utils'
import { Webhook } from '../../entity/webhook'
import axios, { Method } from 'axios'
import { buildLogger } from '../../utils/logger'
const logger = buildLogger('app.dispatch')
import { logger } from '../../utils/logger'
export function webhooksServiceRouter() {
const router = express.Router()
@ -68,14 +66,22 @@ export function webhooksServiceRouter() {
})
logger.info('triggering webhook', url)
await axios.request({
url,
method,
headers: {
'Content-Type': webhook.contentType,
},
data: body,
})
try {
await axios.request({
url,
method,
headers: {
'Content-Type': webhook.contentType,
},
data: body,
})
} catch (error) {
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error(error)
}
}
}
res.status(200).send('OK')

View File

@ -16,13 +16,11 @@ import { shouldSynthesize } from '../services/speech'
import { getClaimsByToken } from '../utils/auth'
import { corsConfig } from '../utils/corsConfig'
import { enqueueTextToSpeech } from '../utils/createTask'
import { buildLogger } from '../utils/logger'
import { logger } from '../utils/logger'
const DEFAULT_VOICE = 'Larry'
const DEFAULT_COMPLIMENTARY_VOICE = 'Evelyn'
const logger = buildLogger('app.dispatch')
export function textToSpeechRouter() {
const router = express.Router()

View File

@ -7,11 +7,9 @@ import { getRepository } from '../entity/utils'
import { env } from '../env'
import { getClaimsByToken, getTokenByRequest } from '../utils/auth'
import { corsConfig } from '../utils/corsConfig'
import { buildLogger } from '../utils/logger'
import { logger } from '../utils/logger'
import { sendEmail } from '../utils/sendEmail'
const logger = buildLogger('app.dispatch')
export function userRouter() {
const router = express.Router()

View File

@ -51,7 +51,11 @@ import { userRouter } from './routers/user_router'
import { sentryConfig } from './sentry'
import { getClaimsByToken, getTokenByRequest } from './utils/auth'
import { corsConfig } from './utils/corsConfig'
import { buildLogger, buildLoggerTransport } from './utils/logger'
import {
buildLogger,
buildLoggerTransport,
CustomTypeOrmLogger,
} from './utils/logger'
const PORT = process.env.PORT || 4000
@ -80,6 +84,7 @@ export const AppDataSource = new DataSource({
entities: [__dirname + '/entity/**/*{.js,.ts}'],
subscribers: [__dirname + '/events/**/*{.js,.ts}'],
namingStrategy: new SnakeNamingStrategy(),
logger: new CustomTypeOrmLogger(),
})
export const createApp = (): {

View File

@ -20,6 +20,7 @@ import {
generateSlug,
pageToArticleSavingRequest,
} from '../utils/helpers'
import { logger } from '../utils/logger'
interface PageSaveRequest {
userId: string
@ -89,7 +90,7 @@ export const createPageSaveRequest = async ({
try {
validateUrl(url)
} catch (error) {
console.log('invalid url', url, error)
logger.info('invalid url', url, error)
return Promise.reject({
errorCode: CreateArticleSavingRequestErrorCode.BadData,
})
@ -100,7 +101,7 @@ export const createPageSaveRequest = async ({
id: userId,
})
if (!user) {
console.log('User not found', userId)
logger.info('User not found', userId)
return Promise.reject({
errorCode: CreateArticleSavingRequestErrorCode.BadData,
})
@ -123,7 +124,7 @@ export const createPageSaveRequest = async ({
url,
})
if (!page) {
console.log('Page not exists', url)
logger.info('Page not exists', url)
page = {
id: articleSavingRequestId,
userId,
@ -145,7 +146,7 @@ export const createPageSaveRequest = async ({
// create processing page
const pageId = await createPage(page, ctx)
if (!pageId) {
console.log('Failed to create page', url)
logger.info('Failed to create page', url)
return Promise.reject({
errorCode: CreateArticleSavingRequestErrorCode.BadData,
})

View File

@ -8,6 +8,7 @@ import { getRepository } from '../entity/utils'
import { SignupErrorCode } from '../generated/graphql'
import { AuthProvider } from '../routers/auth/auth_types'
import { AppDataSource } from '../server'
import { logger } from '../utils/logger'
import { validateUsername } from '../utils/usernamePolicy'
import { sendConfirmationEmail } from './send_emails'
@ -103,13 +104,13 @@ const validateInvite = async (
invite: Invite
): Promise<boolean> => {
if (invite.expirationTime < new Date()) {
console.log('rejecting invite, expired', invite)
logger.info('rejecting invite, expired', invite)
return false
}
const membershipRepo = entityManager.getRepository(GroupMembership)
const numMembers = await membershipRepo.countBy({ invite: { id: invite.id } })
if (numMembers >= invite.maxMembers) {
console.log('rejecting invite, too many users', invite, numMembers)
logger.info('rejecting invite, too many users', invite, numMembers)
return false
}
return true

View File

@ -1,8 +1,9 @@
import * as jwt from 'jsonwebtoken'
import { IsNull, Not } from 'typeorm'
import { Feature } from '../entity/feature'
import { getRepository } from '../entity/utils'
import * as jwt from 'jsonwebtoken'
import { env } from '../env'
import { IsNull, Not } from 'typeorm'
import { logger } from '../utils/logger'
export enum FeatureName {
UltraRealisticVoice = 'ultra-realistic-voice',
@ -33,7 +34,7 @@ const optInUltraRealisticVoice = async (uid: string): Promise<Feature> => {
})
if (feature) {
// already opted in
console.log('already opted in')
logger.info('already opted in')
return feature
}
@ -45,7 +46,7 @@ const optInUltraRealisticVoice = async (uid: string): Promise<Feature> => {
let grantedAt: Date | null = new Date()
if (count >= 1000) {
console.log('feature limit reached')
logger.info('feature limit reached')
grantedAt = null
}

View File

@ -1,15 +1,13 @@
import axios from 'axios'
import { ArticleSavingRequestStatus } from '../../elastic/types'
import { env } from '../../env'
import { buildLogger } from '../../utils/logger'
import { logger } from '../../utils/logger'
import {
IntegrationService,
RetrievedResult,
RetrieveRequest,
} from './integration'
const logger = buildLogger('app.dispatch')
interface PocketResponse {
status: number // 1 if success
complete: number // 1 if all items have been returned
@ -76,7 +74,11 @@ export class PocketIntegration extends IntegrationService {
)
return response.data.access_token
} catch (error) {
logger.error('error validating pocket token', error)
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error(error)
}
return null
}
}
@ -86,7 +88,7 @@ export class PocketIntegration extends IntegrationService {
since: number, // unix timestamp in seconds
count = 100,
offset = 0
): Promise<PocketResponse> => {
): Promise<PocketResponse | null> => {
const url = `${this.POCKET_API_URL}/get`
try {
const response = await axios.post<PocketResponse>(
@ -108,8 +110,13 @@ export class PocketIntegration extends IntegrationService {
return response.data
} catch (error) {
logger.error('error retrieving pocket data', error)
throw new Error('Error retrieving pocket data')
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error(error)
}
return null
}
}
@ -125,6 +132,10 @@ export class PocketIntegration extends IntegrationService {
count,
offset
)
if (!pocketData) {
throw new Error('Error retrieving pocket data')
}
const pocketItems = Object.values(pocketData.list)
const statusToState: Record<string, ArticleSavingRequestStatus> = {
'0': ArticleSavingRequestStatus.Succeeded,

View File

@ -4,6 +4,7 @@ import { Integration } from '../../entity/integration'
import { getRepository } from '../../entity/utils'
import { env } from '../../env'
import { wait } from '../../utils/helpers'
import { logger } from '../../utils/logger'
import { getHighlightUrl } from '../highlights'
import { IntegrationService } from './integration'
@ -48,7 +49,11 @@ export class ReadwiseIntegration extends IntegrationService {
})
return response.status === 204 ? token : null
} catch (error) {
console.error('error validating readwise token', error)
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error(error)
}
return null
}
}
@ -66,7 +71,7 @@ export class ReadwiseIntegration extends IntegrationService {
// update integration syncedAt if successful
if (result) {
console.info('updating integration syncedAt')
logger.info('updating integration syncedAt')
await getRepository(Integration).update(integration.id, {
syncedAt: new Date(),
})
@ -124,19 +129,21 @@ export class ReadwiseIntegration extends IntegrationService {
)
return response.status === 200
} catch (error) {
if (
axios.isAxiosError(error) &&
error.response?.status === 429 &&
retryCount < 3
) {
console.info('Readwise API rate limit exceeded, retrying...')
// wait for Retry-After seconds in the header if rate limited
// max retry count is 3
const retryAfter = error.response?.headers['retry-after'] || '10' // default to 10 seconds
await wait(parseInt(retryAfter, 10) * 1000)
return this.syncWithReadwise(token, highlights, retryCount + 1)
if (axios.isAxiosError(error)) {
if (error.response?.status === 429 && retryCount < 3) {
logger.info('Readwise API rate limit exceeded, retrying...')
// wait for Retry-After seconds in the header if rate limited
// max retry count is 3
const retryAfter = error.response?.headers['retry-after'] || '10' // default to 10 seconds
await wait(parseInt(retryAfter, 10) * 1000)
return this.syncWithReadwise(token, highlights, retryCount + 1)
}
logger.error(error.response)
} else {
logger.error(error)
}
console.error('Error creating highlights in Readwise', error)
return false
}
}

View File

@ -8,6 +8,7 @@ import { User } from '../entity/user'
import { getRepository } from '../entity/utils'
import { CreateLabelInput } from '../generated/graphql'
import { generateRandomColor } from '../utils/helpers'
import { logger } from '../utils/logger'
const INTERNAL_LABELS_IN_LOWERCASE = [
'newsletters',
@ -54,12 +55,12 @@ export const addLabelToPage = async (
let labelEntity = await getLabelByName(user.id, label.name)
if (!labelEntity) {
console.log('creating new label', label.name)
logger.info('creating new label', label.name)
labelEntity = await createLabel(user.id, label)
}
console.log('adding label to page', label.name, pageId)
logger.info('adding label to page', label.name, pageId)
return addLabelInPage(
pageId,
@ -120,7 +121,7 @@ export const createLabels = async (
id: ctx.uid,
})
if (!user) {
console.error('user not found')
logger.error('user not found')
return []
}

View File

@ -6,6 +6,7 @@ import { createPage } from '../elastic/pages'
import { ArticleSavingRequestStatus, Page, PageContext } from '../elastic/types'
import { PageType } from '../generated/graphql'
import { generateSlug, stringToHash } from '../utils/helpers'
import { logger } from '../utils/logger'
type PopularRead = {
url: string
@ -51,7 +52,7 @@ const popularRead = (key: string): PopularRead | undefined => {
originalHtml,
}
} catch (e) {
console.log('error adding popular read', e)
logger.info('error adding popular read', e)
return undefined
}
}

View File

@ -1,7 +1,8 @@
import { getRepository } from '../entity/utils'
import { Reminder } from '../entity/reminder'
import { getPageById } from '../elastic/pages'
import { IsNull, Not } from 'typeorm'
import { getPageById } from '../elastic/pages'
import { Reminder } from '../entity/reminder'
import { getRepository } from '../entity/utils'
import { logger } from '../utils/logger'
export interface PageReminder {
pageId: string
@ -31,7 +32,7 @@ export const getPagesWithReminder = async (
if (reminder.elasticPageId) {
const page = await getPageById(reminder.elasticPageId)
if (!page) {
console.log(`Reminder ${reminder.id} has invalid elasticPageId`)
logger.info(`Reminder ${reminder.id} has invalid elasticPageId`)
continue
}

View File

@ -1,8 +1,9 @@
import { ReportItemInput, ReportType } from '../generated/graphql'
import { ContentDisplayReport } from '../entity/reports/content_display_report'
import { AbuseReport } from '../entity/reports/abuse_report'
import { getPageById } from '../elastic/pages'
import { AbuseReport } from '../entity/reports/abuse_report'
import { ContentDisplayReport } from '../entity/reports/content_display_report'
import { getRepository } from '../entity/utils'
import { ReportItemInput, ReportType } from '../generated/graphql'
import { logger } from '../utils/logger'
export const saveContentDisplayReport = async (
uid: string,
@ -13,7 +14,7 @@ export const saveContentDisplayReport = async (
const page = await getPageById(input.pageId)
if (!page) {
console.log('unable to submit report, page not found', input)
logger.info('unable to submit report, page not found', input)
return false
}
@ -41,12 +42,12 @@ export const saveAbuseReport = async (
const page = await getPageById(input.pageId)
if (!page) {
console.log('unable to submit report, page not found', input)
logger.info('unable to submit report, page not found', input)
return false
}
if (!input.sharedBy) {
console.log('unable to submit report, sharedBy not found', input)
logger.info('unable to submit report, sharedBy not found', input)
return false
}

View File

@ -9,15 +9,13 @@ import {
validatedDate,
wordsCount,
} from '../utils/helpers'
import { buildLogger } from '../utils/logger'
import { logger } from '../utils/logger'
import {
FAKE_URL_PREFIX,
parsePreparedContent,
parseUrlMetadata,
} from '../utils/parser'
const logger = buildLogger('app.dispatch')
export type SaveContext = {
pubsub: PubsubClient
uid: string

View File

@ -1,6 +1,7 @@
import { Knex } from 'knex'
import { PubsubClient } from '../datalayer/pubsub'
import { UserData } from '../datalayer/user/model'
import { updatePage } from '../elastic/pages'
import { homePageURL } from '../env'
import {
ArticleSavingRequestStatus,
@ -9,9 +10,9 @@ import {
SaveResult,
} from '../generated/graphql'
import { DataModels } from '../resolvers/types'
import { createLabels } from './labels'
import { updatePage } from '../elastic/pages'
import { logger } from '../utils/logger'
import { getStorageFileDetails } from '../utils/uploads'
import { createLabels } from './labels'
type SaveContext = {
pubsub: PubsubClient
@ -28,7 +29,7 @@ export const saveFile = async (
saver: UserData,
input: SaveFileInput
): Promise<SaveResult> => {
console.log('saving file with input', input)
logger.info('saving file with input', input)
const pageId = input.clientRequestId
const uploadFile = await ctx.models.uploadFile.getWhere({
id: input.uploadFileId,
@ -70,7 +71,7 @@ export const saveFile = async (
ctx
)
if (!updated) {
console.log('error updating page', pageId)
logger.info('error updating page', pageId)
return {
errorCodes: [SaveErrorCode.Unknown],
}

View File

@ -8,8 +8,8 @@ import { env } from '../env'
import { ContentReader } from '../generated/graphql'
import { analytics } from '../utils/analytics'
import { isBase64Image } from '../utils/helpers'
import { logger } from '../utils/logger'
import { fetchFavicon } from '../utils/parser'
import { sendMulticastPushNotifications } from '../utils/sendNotification'
import { addLabelToPage } from './labels'
import { SaveContext, saveEmail, SaveEmailInput } from './save_email'
import { saveSubscription } from './subscriptions'
@ -46,7 +46,7 @@ export const saveNewsletterEmail = async (
})
if (!data.content) {
console.log('newsletter not created, no content:', data.email)
logger.info('newsletter not created, no content:', data.email)
return false
}
@ -64,7 +64,7 @@ export const saveNewsletterEmail = async (
}
const page = await saveEmail(saveCtx, input)
if (!page) {
console.log('newsletter not created:', input.title)
logger.info('newsletter not created:', input.title)
return false
}
@ -86,19 +86,19 @@ export const saveNewsletterEmail = async (
unsubscribeHttpUrl: data.unsubHttpUrl,
icon,
})
console.log('subscription saved', subscriptionId)
logger.info('subscription saved', subscriptionId)
// adds newsletters label to page
const result = await addLabelToPage(saveCtx, page.id, {
name: 'Newsletter',
color: '#07D2D1',
})
console.log('newsletter label added:', result)
logger.info('newsletter label added:', result)
// sends push notification
const deviceTokens = await getDeviceTokensByUserId(newsletterEmail.user.id)
if (!deviceTokens) {
console.log('Device tokens not set:', newsletterEmail.user.id)
logger.info('Device tokens not set:', newsletterEmail.user.id)
return true
}

View File

@ -22,13 +22,11 @@ import {
validatedDate,
wordsCount,
} from '../utils/helpers'
import { buildLogger } from '../utils/logger'
import { logger } from '../utils/logger'
import { parsePreparedContent } from '../utils/parser'
import { createPageSaveRequest } from './create_page_save_request'
import { createLabels } from './labels'
const logger = buildLogger('app.dispatch')
type SaveContext = {
pubsub: PubsubClient
models: DataModels

View File

@ -4,6 +4,7 @@ import { User } from '../entity/user'
import { getRepository } from '../entity/utils'
import { homePageURL } from '../env'
import { SaveErrorCode, SaveResult, SaveUrlInput } from '../generated/graphql'
import { logger } from '../utils/logger'
import { createPageSaveRequest } from './create_page_save_request'
import { createLabels } from './labels'
@ -45,7 +46,7 @@ export const saveUrl = async (
}`,
}
} catch (error) {
console.log('error enqueuing request', error)
logger.info('error enqueuing request', error)
return {
__typename: 'SaveError',
errorCodes: [SaveErrorCode.Unknown],

View File

@ -3,12 +3,10 @@ import { NewsletterEmail } from '../entity/newsletter_email'
import { Subscription } from '../entity/subscription'
import { getRepository } from '../entity/utils'
import { SubscriptionStatus, SubscriptionType } from '../generated/graphql'
import { buildLogger } from '../utils/logger'
import { logger } from '../utils/logger'
import { sendEmail } from '../utils/sendEmail'
import { createNewsletterEmail } from './newsletters'
const logger = buildLogger('app.dispatch')
interface SaveSubscriptionInput {
userId: string
name: string

View File

@ -8,6 +8,7 @@ import { ApiKey } from '../entity/api_key'
import { getRepository } from '../entity/utils'
import { env } from '../env'
import { Claims, ClaimsToSet } from '../resolvers/types'
import { logger } from './logger'
export const OmnivoreAuthorizationHeader = 'Omnivore-Authorization'
@ -81,7 +82,7 @@ export const getClaimsByToken = async (
e instanceof jwt.JsonWebTokenError &&
!(e instanceof jwt.TokenExpiredError)
) {
console.log(`not a jwt token, checking api key`, { token })
logger.info(`not a jwt token, checking api key`, { token })
return claimsFromApiKey(token)
}

View File

@ -15,14 +15,20 @@ import {
import { signFeatureToken } from '../services/features'
import { generateVerificationToken, OmnivoreAuthorizationHeader } from './auth'
import { CreateTaskError } from './errors'
import { buildLogger } from './logger'
import { logger } from './logger'
import View = google.cloud.tasks.v2.Task.View
const logger = buildLogger('app.dispatch')
// Instantiates a client.
const client = new CloudTasksClient()
const logError = (error: Error): void => {
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error(error)
}
}
const createHttpTaskWithToken = async ({
project = process.env.GOOGLE_CLOUD_PROJECT,
queue = env.queue.name,
@ -245,8 +251,8 @@ export const enqueueParseRequest = async ({
// Calling the handler function directly.
setTimeout(() => {
axios.post(env.queue.contentFetchUrl, payload).catch((error) => {
console.error(error)
console.error(
logError(error)
logger.warning(
`Error occurred while requesting local puppeteer-parse function\nPlease, ensure your function is set up properly and running using "yarn start" from the "/pkg/gcf/puppeteer-parse" folder`
)
})
@ -399,7 +405,7 @@ export const enqueueTextToSpeech = async ({
// Calling the handler function directly.
setTimeout(() => {
axios.post(taskHandlerUrl, payload).catch((error) => {
console.error(error)
logError(error)
})
}, 0)
return ''
@ -450,7 +456,7 @@ export const enqueueRecommendation = async (
headers,
})
.catch((error) => {
console.error(error)
logError(error)
})
}, 0)
return ''
@ -494,7 +500,7 @@ export const enqueueImportFromIntegration = async (
headers,
})
.catch((error) => {
console.error(error)
logError(error)
})
}, 0)
return nanoid()
@ -543,7 +549,7 @@ export const enqueueThumbnailTask = async (
headers,
})
.catch((error) => {
console.error(error)
logError(error)
})
}, 0)
return ''
@ -590,7 +596,7 @@ export const enqueueRssFeedFetch = async (
headers,
})
.catch((error) => {
console.error(error)
logError(error)
})
}, 0)
return nanoid()

View File

@ -20,7 +20,7 @@ import { CreateArticlesSuccessPartial } from '../resolvers'
import { Claims, WithDataSourcesContext } from '../resolvers/types'
import { validateUrl } from '../services/create_page_save_request'
import { Merge } from '../util'
import { logger } from './logger'
interface InputObject {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any
@ -225,7 +225,7 @@ export const validatedDate = (
}
return new Date(date)
} catch (e) {
console.log('error validating date', date, e)
logger.error('error validating date', date, e)
return undefined
}
}
@ -247,7 +247,7 @@ export const titleForFilePath = (url: string): string => {
const title = decodeURI(path.basename(new URL(url).pathname, '.pdf'))
return title
} catch (e) {
console.log(e)
logger.error(e)
}
return url
}
@ -299,7 +299,7 @@ export const isUrl = (str: string): boolean => {
validateUrl(str)
return true
} catch {
console.log('not an url', str)
logger.error('not an url', str)
return false
}
}

View File

@ -3,9 +3,7 @@ import { parseHTML } from 'linkedom'
import { nanoid } from 'nanoid'
import { v4 as uuidv4 } from 'uuid'
import { interpolationSearch } from './interpolationSearch'
import { buildLogger } from './logger'
const logger = buildLogger('app.dispatch')
import { logger } from './logger'
const highlightTag = 'omnivore_highlight'
export const maxHighlightLength = 2000

View File

@ -3,6 +3,12 @@
import { LoggingWinston } from '@google-cloud/logging-winston'
import { cloneDeep, isArray, isObject, isString, truncate } from 'lodash'
import { DateTime } from 'luxon'
import {
AdvancedConsoleLogger,
Logger as TypeOrmLogger,
LoggerOptions as TypeOrmLoggerOptions,
QueryRunner,
} from 'typeorm'
import {
config,
format,
@ -15,6 +21,30 @@ import TransportStream from 'winston-transport'
import { ConsoleTransportOptions } from 'winston/lib/winston/transports'
import { env } from '../env'
export class CustomTypeOrmLogger
extends AdvancedConsoleLogger
implements TypeOrmLogger
{
private logger: Logger
constructor(options?: TypeOrmLoggerOptions) {
super(options)
this.logger = buildLogger('typeorm')
}
logQuery(query: string, parameters?: any[], queryRunner?: QueryRunner) {
this.logger.debug(query, parameters, queryRunner)
}
log(
level: 'log' | 'info' | 'warn',
message: any,
queryRunner?: QueryRunner
): void {
this.logger.log(level, message, queryRunner)
}
}
const colors = {
emerg: 'inverse underline magenta',
alert: 'underline magenta',
@ -125,4 +155,6 @@ export interface LogRecord {
[key: string]: any
}
export const logger = buildLogger('app')
export default {}

View File

@ -454,8 +454,12 @@ export const parseUrlMetadata = async (
try {
const res = await axios.get(url)
return parsePageMetadata(res.data)
} catch (e) {
logger.info('failed to get:', url, e)
} catch (error) {
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error(error)
}
return undefined
}
}
@ -500,7 +504,11 @@ export const fetchFavicon = async (
const domain = new URL(realUrl).hostname
return `https://api.faviconkit.com/${domain}/128`
} catch (e) {
console.log('Error fetching favicon', e)
if (axios.isAxiosError(e)) {
logger.error('failed to get favicon:', e.response?.status)
} else {
logger.error('failed to get favicon:', e)
}
return undefined
}
}
@ -689,8 +697,12 @@ export const getDistillerResult = async (
timeout: 5000,
})
return response.data
} catch (e) {
logger.info('Error parsing by distiller', e)
} catch (error) {
if (axios.isAxiosError(error)) {
logger.error(error.response)
} else {
logger.error(error)
}
return undefined
}
}

View File

@ -1,6 +1,7 @@
import { MailService } from '@sendgrid/mail'
import { MailDataRequired } from '@sendgrid/helpers/classes/mail'
import { MailService } from '@sendgrid/mail'
import { env } from '../env'
import { logger } from './logger'
type SendGridResponse = {
body?: string
@ -25,7 +26,7 @@ export const sendEmail = async (msg: MailDataRequired): Promise<boolean> => {
const client = new MailService()
if (!process.env.SENDGRID_MSGS_API_KEY) {
if (env.dev.isLocal) {
console.log('SendGrid API key not set.\nSending email:', msg)
logger.warning('SendGrid API key not set.\nSending email:', msg)
return true
}
@ -34,18 +35,19 @@ export const sendEmail = async (msg: MailDataRequired): Promise<boolean> => {
client.setApiKey(process.env.SENDGRID_MSGS_API_KEY)
console.log('sending email', msg)
logger.info('sending email', msg)
try {
const response = await client.send(msg)
console.log('email sent', response)
logger.info('email sent', response)
return true
} catch (error) {
console.log('error sending email', error)
const err = asSendGridError(error)
if (err) {
console.log('sendgrid error:', JSON.stringify(err.response?.body))
logger.error('sendgrid error:', JSON.stringify(err.response?.body))
} else {
logger.error('error sending email', error)
}
return false

View File

@ -7,6 +7,7 @@ import {
} from 'firebase-admin/messaging'
import { env } from '../env'
import { analytics } from './analytics'
import { logger } from './logger'
export type PushNotificationType = 'newsletter' | 'reminder' | 'rule'
@ -32,11 +33,11 @@ export const sendPushNotification = async (
})
const res = await getMessaging().send(message)
console.log(res)
logger.info(res)
return res
} catch (err) {
console.log('firebase cloud message error: ', err)
logger.error('firebase cloud message error: ', err)
return undefined
}
@ -58,13 +59,13 @@ export const sendMulticastPushNotifications = async (
},
})
console.log('sending multicast message: ', JSON.stringify(message))
logger.info('sending multicast message: ', JSON.stringify(message))
const res = await getMessaging().sendMulticast(message)
console.log('send notification result: ', JSON.stringify(res.responses))
logger.info('send notification result: ', JSON.stringify(res.responses))
return res
} catch (err) {
console.log('firebase cloud message error: ', err)
logger.error('firebase cloud message error: ', err)
return undefined
}
@ -75,11 +76,11 @@ export const sendBatchPushNotifications = async (
): Promise<BatchResponse | undefined> => {
try {
const res = await getMessaging().sendAll(messages)
console.log('success count: ', res.successCount)
logger.info('success count: ', res.successCount)
return res
} catch (err) {
console.log('firebase cloud message error: ', err)
logger.error('firebase cloud message error: ', err)
return undefined
}

View File

@ -3,6 +3,7 @@
import { File, GetSignedUrlConfig, Storage } from '@google-cloud/storage'
import { env } from '../env'
import { ContentReader, PageType } from '../generated/graphql'
import { logger } from './logger'
export const contentReaderForPage = (
pageType: PageType,
@ -57,7 +58,7 @@ export const generateUploadSignedUrl = async (
expires: Date.now() + 15 * 60 * 1000, // 15 minutes
contentType: contentType,
}
console.log('signed url for: ', options)
logger.info('signed url for: ', options)
// Get a v4 signed URL for uploading file
const [url] = await storage
@ -79,7 +80,7 @@ export const generateDownloadSignedUrl = async (
.bucket(bucketName)
.file(filePathName)
.getSignedUrl(options)
console.log('generating download signed url', url)
logger.info('generating download signed url', url)
return url
}