@@ -279,27 +279,29 @@ export const processStack = (error, stacktrace) => {
279279 let isInternal = false ;
280280 let p5FileName , friendlyStack ;
281281
282+ // Helper to strip query strings and hashes from URLs for consistent matching
283+ const cleanUrl = url => ( typeof url === 'string' ? url . split ( '?' ) [ 0 ] . split ( '#' ) [ 0 ] : '' ) ;
284+
282285 // Intentionally throw an error that we catch so that we can check the name
283286 // of the current file. Any errors we see from this file, we treat as
284287 // internal errors.
285288 const testStacktrace = errorStackParser . parse ( Error ( ) ) ;
286- p5FileName = testStacktrace [ 0 ] . fileName ;
289+ p5FileName = cleanUrl ( testStacktrace [ 0 ] ?. fileName ) ;
290+ const p5BaseName = p5FileName ? p5FileName . split ( '/' ) . slice ( - 1 ) [ 0 ] : '' ;
291+ const isP5File = url => {
292+ const cleaned = cleanUrl ( url ) ;
293+ if ( ! cleaned ) return false ;
294+ if ( cleaned === p5FileName ) return true ;
295+ if ( p5BaseName && cleaned . split ( '/' ) . slice ( - 1 ) [ 0 ] === p5BaseName ) return true ;
296+ return false ;
297+ } ;
287298
288299 for ( let i = stacktrace . length - 1 ; i >= 0 ; i -- ) {
289300 let splitted = stacktrace [ i ] . functionName . split ( '.' ) ;
290301 if ( entryPoints . includes ( splitted [ splitted . length - 1 ] ) ) {
291302 // remove everything below an entry point function (setup, draw, etc).
292303 // (it's usually the internal initialization calls)
293304 friendlyStack = stacktrace . slice ( 0 , i + 1 ) ;
294- // We call the error "internal" if the source of the error was a
295- // function from within the p5.js library file, but called from the
296- // user's code directly. We only need to check the topmost frame in
297- // the stack trace since any function internal to p5 should pass this
298- // check, not just public p5 functions.
299- if ( stacktrace [ 0 ] . fileName === p5FileName ) {
300- isInternal = true ;
301- break ;
302- }
303305 break ;
304306 }
305307 }
@@ -309,6 +311,14 @@ export const processStack = (error, stacktrace) => {
309311 // entire stacktrace for friendlyStack
310312 if ( ! friendlyStack ) friendlyStack = stacktrace ;
311313
314+ // We call the error "internal" if the source of the error was a
315+ // function from within the p5.js library file, but called from the
316+ // user's code directly. When error is null (called from param_validator),
317+ // it is always an internal validation call.
318+ if ( error === null || isP5File ( stacktrace [ 0 ] ?. fileName ) ) {
319+ isInternal = true ;
320+ }
321+
312322 if ( isInternal ) {
313323 // the frameIndex property is added before the filter, so frameIndex
314324 // corresponds to the index of a frame in the original stacktrace.
@@ -319,7 +329,15 @@ export const processStack = (error, stacktrace) => {
319329 frame . frameIndex = index ;
320330 return frame ;
321331 } )
322- . filter ( frame => frame . fileName !== p5FileName ) ;
332+ . filter ( frame => {
333+ const cleaned = cleanUrl ( frame . fileName ) ;
334+ return (
335+ cleaned &&
336+ ! isP5File ( frame . fileName ) &&
337+ cleaned !== '<anonymous>' &&
338+ ! cleaned . startsWith ( 'eval' )
339+ ) ;
340+ } ) ;
323341
324342 // a weird case, if for some reason we can't identify the function called
325343 // from user's code
@@ -332,16 +350,19 @@ export const processStack = (error, stacktrace) => {
332350 friendlyStack [ 0 ] . lineNumber &&
333351 friendlyStack [ 0 ] . columnNumber
334352 ) {
353+ const cleanFile = cleanUrl ( friendlyStack [ 0 ] . fileName ) ;
335354 locationObj = {
336- location : `${ friendlyStack [ 0 ] . fileName } :${
355+ location : `${ cleanFile } :${
337356 friendlyStack [ 0 ] . lineNumber
338357 } :${ friendlyStack [ 0 ] . columnNumber } `,
339- file : friendlyStack [ 0 ] . fileName . split ( '/' ) . slice ( - 1 ) ,
358+ file : cleanFile . split ( '/' ) . slice ( - 1 ) [ 0 ] ,
340359 line : friendlyStack [ 0 ] . lineNumber
341360 } ;
342361
343362 // if already handled by another part of the FES, don't handle again
344- if ( p5 . _fesLogCache [ locationObj . location ] ) return [ true , null ] ;
363+ if ( typeof p5 !== 'undefined' && p5 ?. _fesLogCache ?. [ locationObj . location ] ) {
364+ return [ true , null ] ;
365+ }
345366 }
346367
347368 // Library error
@@ -394,8 +415,16 @@ export function printFriendlyStack(friendlyStack) {
394415}
395416
396417export function getFriendlyStack ( stacktrace , compact = false ) {
418+ if ( ! stacktrace || ! stacktrace . length || ! stacktrace [ 0 ] ?. fileName ) {
419+ return null ;
420+ }
421+ const rawFile = stacktrace [ 0 ] . fileName ;
422+ const cleanFile = ( typeof rawFile === 'string' ? rawFile . split ( '?' ) [ 0 ] . split ( '#' ) [ 0 ] : '' ) . split ( '/' ) . slice ( - 1 ) [ 0 ] ;
423+ if ( ! cleanFile || cleanFile === '<anonymous>' || cleanFile . startsWith ( 'eval' ) ) {
424+ return null ;
425+ }
397426 if ( compact ) {
398- return `[${ stacktrace [ 0 ] . fileName . split ( '/' ) . slice ( - 1 ) } , line ${ stacktrace [ 0 ] . lineNumber } ]` ;
427+ return `[${ cleanFile } , line ${ stacktrace [ 0 ] . lineNumber } ]` ;
399428 } else {
400429 if ( stacktrace . length > 1 ) {
401430 let stacktraceMsg = '' ;
0 commit comments