@@ -8,24 +8,26 @@ const lastLineTypeMessage = (raw: string) => {
88} ;
99
1010export const skulptAdapter : AdapterFn = ( raw , code ) => {
11- if ( ! / s k u l p t / i. test ( raw ) && ! / T r a c e b a c k / i. test ( raw ) ) {
12- // still try; skulpt often includes "on line X of", etc.
13- }
11+ // Skulpt traces vary - we accept both "Traceback..." and editor summaries
1412 const { type, message, tail, lines } = lastLineTypeMessage ( raw ) ;
1513 let file : string | undefined , line : number | undefined , col : number | undefined ;
1614
15+ // standard Python-style frames (Skulpt often emits these)
1716 for ( const L of lines ) {
1817 const mm = L . match ( / F i l e \s + " ( [ ^ " ] + ) " , \s + l i n e \s + ( \d + ) / i) ;
1918 if ( mm ) {
2019 file = mm [ 1 ] ;
2120 line = parseInt ( mm [ 2 ] , 10 ) ;
2221 }
2322 }
23+
2424 if ( ! line ) {
25- const loc = tail . match ( / \b (?: o n | a t ) \s + l i n e \s + ( \d + ) \s + (?: o f | i n ) \s + ( [ ^ \s : ] + ) \b / i) ;
26- if ( loc ) {
27- line = parseInt ( loc [ 1 ] , 10 ) ;
28- file = loc [ 2 ] ;
25+ const m1 = raw . match ( / o n \s + l i n e \s + ( \d + ) \s + o f \s + ( [ ^ \s : ] + ) (?: : \s * ( [ \s \S ] * ) ) ? / i) ;
26+ if ( m1 ) {
27+ line = parseInt ( m1 [ 1 ] , 10 ) ;
28+ file = m1 [ 2 ] ;
29+ const afterColon = ( m1 [ 3 ] || "" ) . split ( / \r ? \n / ) ;
30+ const snippet = afterColon . find ( s => s . trim ( ) && ! / ^ \s * \^ + \s * $ / . test ( s ) ) ;
2931 }
3032 }
3133
@@ -46,10 +48,20 @@ export const skulptAdapter: AdapterFn = (raw, code) => {
4648 } ;
4749
4850 if ( code && line ) {
49- const lines = code . split ( / \r ? \n / ) ;
50- t . codeLine = lines [ line - 1 ] ?. trim ( ) ;
51- t . codeBefore = lines . slice ( Math . max ( 0 , line - 3 ) , line - 1 ) ;
52- t . codeAfter = lines . slice ( line , line + 2 ) ;
51+ const codeLines = code . split ( / \r ? \n / ) ;
52+ t . codeLine = codeLines [ line - 1 ] ?. trim ( ) ;
53+ t . codeBefore = codeLines . slice ( Math . max ( 0 , line - 3 ) , line - 1 ) ;
54+ t . codeAfter = codeLines . slice ( line , line + 2 ) ;
55+ } else {
56+ const m1 = raw . match ( / o n \s + l i n e \s + \d + \s + o f \s + [ ^ \s : ] + : (?: \s * ( [ \s \S ] * ) ) ? / i) ;
57+ if ( m1 && m1 [ 1 ] ) {
58+ const snippet = m1 [ 1 ] . split ( / \r ? \n / ) . find ( s => s . trim ( ) && ! / ^ \s * \^ + \s * $ / . test ( s ) ) ;
59+ if ( snippet ) t . codeLine = snippet . trim ( ) ;
60+ }
5361 }
62+
63+ const looksLikeError = / E r r o r \b / i. test ( raw ) || / T r a c e b a c k / i. test ( raw ) || / s k u l p t / i. test ( raw ) ;
64+ if ( ! looksLikeError ) return null ;
65+
5466 return t ;
5567} ;
0 commit comments