Hi @cjReimer great question. I don’t know if there is a standard way – I kow I wanted to see how people best used it and then come up with a consensus “standard” … but this is what I have done:
First, if the exception is in GraphQL hander – then you can log it there. Soon there will be some better logging support once Redwood moves to use Helix and envelop.
You can import logger in graphql.ts
and use formatError()
:
import {
createGraphQLHandler,
makeMergedSchema,
makeServices,
AuthenticationError,
ForbiddenError,
ValidationError,
} from '@redwoodjs/api'
import schemas from 'src/graphql/**/*.{js,ts}'
import services from 'src/services/**/*.{js,ts}'
import { getCurrentUser } from 'src/lib/auth'
import { db } from 'src/lib/db'
import { logger } from 'src/lib/logger'
export const handler = createGraphQLHandler({
formatError: (error) => {
const originalError = error.originalError
logger.error(
{ graphQL: error, originalError: originalError },
error.message
)
if (originalError instanceof ValidationError) {
return new ValidationError('Validation failed.')
} else if (originalError instanceof ForbiddenError) {
return new ForbiddenError(originalError.message)
} else if (originalError instanceof AuthenticationError) {
return new AuthenticationError(originalError.message)
} else {
return new Error('An error occurred.')
}
},
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
getCurrentUser,
onException: () => {
// Disconnect from your database with an unhandled exception.
db.$disconnect()
},
})
Again, this will get easier in a bit. Also, plan to add operation name, query variables and other useful info in dev to help debug.
Also, you can force console log to go use the logger by binding it to the logger as in the last line here (this would be in logger.ts): console.log = logger.info.bind(logger)
import { createLogger, isTest } from '@redwoodjs/api/logger'
/**
* Creates a logger with RedwoodLoggerOptions
*
* These extend and override default LoggerOptions,
* can define a destination like a file or other supported pino log transport stream,
* and sets whether or not to show the logger configuration settings (defaults to false)
*
* @param RedwoodLoggerOptions
*
* RedwoodLoggerOptions have
* @param {options} LoggerOptions - defines how to log, such as pretty printing, redaction, and format
* @param {string | DestinationStream} destination - defines where to log, such as a transport stream or file
* @param {boolean} showConfig - whether to display logger configuration on initialization
*/
export const logger = createLogger({})
console.log = logger.info.bind(logger)
You can choose the level for console.log to use by binding to info
or what level best suits you.
If you are getting the exception in a serverless function or webhook, you need to catch and log as needed.