@@ -303,13 +303,18 @@ struct PendingInputs {
303303 index : isize ,
304304}
305305
306+ enum ParseResult < T > {
307+ Success ( Option < T > ) ,
308+ SyntaxError ( String ) ,
309+ }
310+
306311impl PendingInputs {
307- pub ( crate ) fn read ( input : & str ) -> anyhow:: Result < Option < Self > > {
312+ pub ( crate ) fn read ( input : & str ) -> anyhow:: Result < ParseResult < PendingInputs > > {
308313 let status = match harp:: parse_status ( & harp:: ParseInput :: Text ( input) ) {
309314 Err ( err) => {
310315 // Failed to even attempt to parse the input, something is seriously wrong
311316 // FIXME: There are some valid syntax errors going through here, e.g. `identity |> _(1)`.
312- return Err ( anyhow ! ( "Failed to parse input: {err:?}" ) ) ;
317+ return Ok ( ParseResult :: SyntaxError ( format ! ( "{err}" ) ) ) ;
313318 } ,
314319 Ok ( status) => status,
315320 } ;
@@ -321,10 +326,12 @@ impl PendingInputs {
321326 let exprs = match status {
322327 harp:: ParseResult :: Complete ( exprs) => exprs,
323328 harp:: ParseResult :: Incomplete => {
324- return Err ( anyhow ! ( "Can't execute incomplete input:\n {input}" ) ) ;
329+ return Ok ( ParseResult :: SyntaxError ( format ! (
330+ "Can't execute incomplete input:\n {input}"
331+ ) ) ) ;
325332 } ,
326333 harp:: ParseResult :: SyntaxError { message, .. } => {
327- return Err ( anyhow ! ( "Syntax error: {message}" ) ) ;
334+ return Ok ( ParseResult :: SyntaxError ( format ! ( "Syntax error: {message}" ) ) ) ;
328335 } ,
329336 } ;
330337
@@ -334,15 +341,15 @@ impl PendingInputs {
334341 let index = 0 ;
335342
336343 if len == 0 {
337- return Ok ( None ) ;
344+ return Ok ( ParseResult :: Success ( None ) ) ;
338345 }
339346
340- Ok ( Some ( Self {
347+ Ok ( ParseResult :: Success ( Some ( Self {
341348 exprs,
342349 srcrefs,
343350 len,
344351 index,
345- } ) )
352+ } ) ) )
346353 }
347354
348355 pub ( crate ) fn is_empty ( & self ) -> bool {
@@ -444,7 +451,7 @@ pub(crate) enum ConsoleResult {
444451 NewPendingInput ( PendingInput ) ,
445452 Interrupt ,
446453 Disconnected ,
447- Error ( amalthea :: Error ) ,
454+ Error ( String ) ,
448455}
449456
450457impl RMain {
@@ -1262,10 +1269,17 @@ impl RMain {
12621269 ConsoleInput :: Input ( code) => {
12631270 // Parse input into pending expressions
12641271 match PendingInputs :: read ( & code) {
1265- Ok ( inputs) => {
1272+ Ok ( ParseResult :: Success ( inputs) ) => {
12661273 self . pending_inputs = inputs;
12671274 } ,
1268- Err ( err) => return Some ( ConsoleResult :: Error ( amalthea:: anyhow!( "{err:?}" ) ) ) ,
1275+ Ok ( ParseResult :: SyntaxError ( message) ) => {
1276+ return Some ( ConsoleResult :: Error ( message) )
1277+ } ,
1278+ Err ( err) => {
1279+ return Some ( ConsoleResult :: Error ( format ! (
1280+ "Error while parsing input: {err:?}"
1281+ ) ) )
1282+ } ,
12691283 }
12701284
12711285 // Evaluate first expression if there is one
@@ -1439,7 +1453,7 @@ impl RMain {
14391453 log:: info!( "Detected `readline()` call in renv autoloader. Returning `'{input}'`." ) ;
14401454 match Self :: on_console_input ( buf, buflen, input) {
14411455 Ok ( ( ) ) => return ConsoleResult :: NewInput ,
1442- Err ( err) => return ConsoleResult :: Error ( err) ,
1456+ Err ( err) => return ConsoleResult :: Error ( format ! ( "{ err}" ) ) ,
14431457 }
14441458 }
14451459
@@ -1450,7 +1464,7 @@ impl RMain {
14501464 "Are you calling `readline()` or `menu()` from an `.Rprofile` or `.Rprofile.site` file? If so, that is the issue and you should remove that code."
14511465 ] . join ( "\n " ) ;
14521466
1453- return ConsoleResult :: Error ( Error :: InvalidInputRequest ( message) ) ;
1467+ return ConsoleResult :: Error ( message) ;
14541468 }
14551469
14561470 fn start_debug ( & mut self , debug_preserve_focus : bool ) {
@@ -1607,10 +1621,10 @@ impl RMain {
16071621 let input = convert_line_endings ( & input. value , LineEnding :: Posix ) ;
16081622 match Self :: on_console_input ( buf, buflen, input) {
16091623 Ok ( ( ) ) => ConsoleResult :: NewInput ,
1610- Err ( err) => ConsoleResult :: Error ( err) ,
1624+ Err ( err) => ConsoleResult :: Error ( format ! ( "{ err:?}" ) ) ,
16111625 }
16121626 } ,
1613- Err ( err) => ConsoleResult :: Error ( err) ,
1627+ Err ( err) => ConsoleResult :: Error ( format ! ( "{ err:?}" ) ) ,
16141628 }
16151629 }
16161630
@@ -2328,14 +2342,6 @@ impl RMain {
23282342 }
23292343 }
23302344
2331- fn propagate_error ( & mut self , message : String ) -> ! {
2332- // Save error message to `RMain`'s buffer to avoid leaking memory when `Rf_error()` jumps.
2333- // Some gymnastics are required to deal with the possibility of `CString` conversion failure
2334- // since the error message comes from the frontend and might be corrupted.
2335- self . r_error_buffer = Some ( new_cstring ( message) ) ;
2336- unsafe { Rf_error ( self . r_error_buffer . as_ref ( ) . unwrap ( ) . as_ptr ( ) ) }
2337- }
2338-
23392345 #[ cfg( not( test) ) ] // Avoid warnings in unit test
23402346 pub ( crate ) fn read_console_frame ( & self ) -> RObject {
23412347 self . read_console_frame . borrow ( ) . clone ( )
@@ -2545,8 +2551,13 @@ fn r_read_console_impl(
25452551 return 0 ;
25462552 } ,
25472553
2548- ConsoleResult :: Error ( err) => {
2549- main. propagate_error ( format ! ( "{err}" ) ) ;
2554+ ConsoleResult :: Error ( message) => {
2555+ // Save error message in `RMain` to avoid leaking memory when
2556+ // `Rf_error()` jumps. Some gymnastics are required to deal with the
2557+ // possibility of `CString` conversion failure since the error
2558+ // message comes from the frontend and might be corrupted.
2559+ main. r_error_buffer = Some ( new_cstring ( message) ) ;
2560+ unsafe { Rf_error ( main. r_error_buffer . as_ref ( ) . unwrap ( ) . as_ptr ( ) ) }
25502561 } ,
25512562 } ;
25522563}
0 commit comments