Skip to content

Instantly share code, notes, and snippets.

@KeKs0r
Created July 26, 2022 08:58
Show Gist options
  • Save KeKs0r/ece9a454561bb864f806549d3b8e715c to your computer and use it in GitHub Desktop.
Save KeKs0r/ece9a454561bb864f806549d3b8e715c to your computer and use it in GitHub Desktop.
Replicache Log Sink
import { parse } from 'querystring'
import type { LogSink } from 'replicache'
import { isPlainObject } from 'lodash'
import { logger } from '@laserfocus/ui/logger'
// Those just wrap the sentry SDK
import { captureException, setExtra } from '@laserfocus/ui/error-reporting'
import { WrappedBaseError, BaseError } from '@laserfocus/shared/util-error'
class WrappedReplicacheError extends WrappedBaseError {
isOperational = true
name = 'WrappedReplicacheError'
}
class ReplicacheError extends BaseError {
isOperational = true
name = 'ReplicacheError'
}
export const SentryLogSink: LogSink = {
log(level, ...args) {
if (level === 'error') {
const parsed = parseLogSinkMessage(args)
try {
if (typeof navigator.storage?.estimate === 'function') {
// Add Storage info to replicache related errors
navigator.storage.estimate().then((quota) => {
setExtra('storage', quota)
captureException(parsed)
})
} else {
captureException(parsed)
}
} catch (e: unknown) {
console.error(e)
}
captureException(parsed)
} else if (level === 'info') {
logger.info(...args)
}
},
}
export function parseLogSinkMessage(args: unknown[]): WrappedReplicacheError | ReplicacheError {
const message: string =
args.filter(isString).find((a) => !a.includes('=')) || 'Replicache Error'
const remaining = args.filter((a) => a !== message)
const initialContext: Record<string, string | string[] | undefined> = {}
const contextStringArgs: string[] = remaining.filter(isString).filter((a) => a.includes('='))
const contextValues = contextStringArgs.reduce((context, curr) => {
const parsed = parse(curr)
return {
...context,
...parsed,
}
}, initialContext)
const cause = remaining.find(isCause)
if (cause) {
return new WrappedReplicacheError(message, cause, contextValues)
}
return new ReplicacheError(message, contextValues)
}
function isString(a: unknown): a is string {
return typeof a === 'string'
}
function isCause(a: unknown): a is Error {
return a instanceof Error || isErrorIsh(a)
}
function isErrorIsh(a: any) {
return isPlainObject(a) && a?.name && a?.stack && a?.message
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment