Skip to content

Commit

Permalink
Merge branch 'master' into tordev
Browse files Browse the repository at this point in the history
  • Loading branch information
riccardobl authored Nov 4, 2024
2 parents c708c5b + d9e9a67 commit 048c27f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 4 deletions.
7 changes: 4 additions & 3 deletions components/error-boundary.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import copy from 'clipboard-copy'
import { LoggerContext } from './logger'
import Button from 'react-bootstrap/Button'
import { useToast } from './toast'

import { decodeMinifiedStackTrace } from '@/lib/stacktrace'
class ErrorBoundary extends Component {
constructor (props) {
super(props)
Expand All @@ -27,7 +27,7 @@ class ErrorBoundary extends Component {
getErrorDetails () {
let details = this.state.error.stack
if (this.state.errorInfo?.componentStack) {
details += `\n\nComponent stack:${this.state.errorInfo.componentStack}`
details += `\n\nComponent stack:\n ${this.state.errorInfo.componentStack}`
}
return details
}
Expand Down Expand Up @@ -69,7 +69,8 @@ const CopyErrorButton = ({ errorDetails }) => {
const toaster = useToast()
const onClick = async () => {
try {
await copy(errorDetails)
const decodedDetails = await decodeMinifiedStackTrace(errorDetails)
await copy(decodedDetails)
toaster?.success?.('copied')
} catch (err) {
console.error(err)
Expand Down
55 changes: 55 additions & 0 deletions lib/stacktrace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { SourceMapConsumer } from 'source-map'

// FUN@FILE:LINE:COLUMN
const STACK_TRACE_LINE_REGEX = /^([A-Za-z0-9]*)@(.*):([0-9]+):([0-9]+)/

/**
* Decode a minified stack trace using source maps
* @param {string} stack - the minified stack trace
* @param {Object<string, SourceMapConsumer>} [sourceMaps] - an object used to cache source maps
* @returns {Promise<string>} Decoded stack trace
*/
export async function decodeMinifiedStackTrace (stack, sourceMaps = {}) {
let decodedStack = ''
let decoded = false
for (const line of stack.split('\n')) {
try {
const stackLine = line.trim()
const stackLineParts = stackLine?.match(STACK_TRACE_LINE_REGEX)
if (stackLineParts) {
const [stackFile, stackLine, stackColumn] = stackLineParts.slice(2)
if (!stackFile || !stackLine || !stackColumn) throw new Error('Unsupported stack line')
if (
(
!stackFile.startsWith(process.env.NEXT_PUBLIC_ASSET_PREFIX) &&
!stackFile.startsWith(process.env.NEXT_PUBLIC_URL)
) ||
!stackFile.endsWith('.js')
) throw new Error('Unsupported file url ' + stackFile)
const sourceMapUrl = stackFile + '.map'
if (!sourceMaps[sourceMapUrl]) {
sourceMaps[sourceMapUrl] = await new SourceMapConsumer(await fetch(sourceMapUrl).then(res => res.text()))
}
const sourceMapper = sourceMaps[sourceMapUrl]
const map = sourceMapper.originalPositionFor({
line: parseInt(stackLine),
column: parseInt(stackColumn)
})
const { source, name, line, column } = map
if (!source || line === undefined) throw new Error('Unsupported stack line')
decodedStack += `${name || ''}@${source}:${line}:${column}\n`
decoded = true
continue
}
} catch (e) {
console.error('Cannot decode stack line', e)
}
decodedStack += `${line}\n`
}

if (decoded) {
decodedStack = `Decoded stacktrace:\n${decodedStack}\n\nOriginal stack trace:\n${stack}`
}

return decodedStack
}
7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"remove-markdown": "^0.5.5",
"sass": "^1.79.5",
"serviceworker-storage": "^0.1.0",
"source-map": "^0.8.0-beta.0",
"textarea-caret": "^3.1.0",
"tldts": "^6.1.51",
"tsx": "^4.19.1",
Expand Down

0 comments on commit 048c27f

Please sign in to comment.