@@ -677,10 +677,17 @@ static VALUE parse_error_new(JSON_ParserState *state, VALUE message, long line,
677677
678678NORETURN (static ) void raise_parse_error (const char * format , JSON_ParserState * state , bool eos )
679679{
680- VALUE message = build_parse_error_message (format , state );
681- if (state -> parser ) { // line and columns can't be accurate in resumable
682- rb_exc_raise (parse_error_new (state , message , 0 , 0 , eos ));
680+ if (state -> parser ) {
681+ if (eos ) {
682+ // the error will be swallowed by ResumableParser#parse, so no
683+ // point building a message or backtrace.
684+ rb_throw_obj (state -> parser , state -> parser );
685+ } else {
686+ // line and columns can't be accurate in resumable
687+ rb_exc_raise (parse_error_new (state , build_parse_error_message (format , state ), 0 , 0 , eos ));
688+ }
683689 } else {
690+ VALUE message = build_parse_error_message (format , state );
684691 long line , column ;
685692 cursor_position (state , & line , & column );
686693 rb_str_catf (message , " at line %ld column %ld" , line , column );
@@ -2379,14 +2386,25 @@ static VALUE cResumableParser_feed(VALUE self, VALUE str)
23792386struct json_parse_any_args {
23802387 JSON_ParserState * state ;
23812388 JSON_ParserConfig * config ;
2389+ VALUE parser ;
23822390};
23832391
2384- static VALUE json_parse_any_resumable_safe ( VALUE _args )
2392+ static VALUE json_parse_any_resumable_safe0 ( RB_BLOCK_CALL_FUNC_ARGLIST ( yielded_arg , _args ) )
23852393{
23862394 struct json_parse_any_args * args = (struct json_parse_any_args * )_args ;
23872395 return (VALUE )json_parse_any (args -> state , args -> config , true);
23882396}
23892397
2398+ static VALUE json_parse_any_resumable_safe (VALUE _args )
2399+ {
2400+ struct json_parse_any_args * args = (struct json_parse_any_args * )_args ;
2401+ VALUE result = rb_catch_obj (args -> parser , json_parse_any_resumable_safe0 , _args );
2402+ if (result == args -> parser ) {
2403+ return (VALUE )false;
2404+ }
2405+ return result ;
2406+ }
2407+
23902408static JSON_ResumableParser * ResumableParser_acquire (VALUE self , bool lock )
23912409{
23922410 JSON_ResumableParser * parser = cResumableParser_get (self );
@@ -2455,25 +2473,20 @@ static VALUE cResumableParser_parse(VALUE self)
24552473 struct json_parse_any_args args = {
24562474 .state = & parser -> state ,
24572475 .config = & parser -> config ,
2476+ .parser = self ,
24582477 };
24592478 int status ;
24602479 const char * initial_cursor = parser -> state .cursor ;
24612480 parser -> complete = rb_protect (json_parse_any_resumable_safe , (VALUE )& args , & status );
2481+
24622482 if (status ) {
2463- VALUE error_source = rb_ivar_get (rb_errinfo (), i_at_eos );
2464- if (error_source == self ) {
2465- parser -> complete = false; // is an EOS error raised by ourself
2466- rb_set_errinfo (Qnil );
2467- status = 0 ;
2468- } else {
2469- parser -> complete = true; // a parse error is considered complete
2470- }
2483+ parser -> complete = true; // a parse error is considered complete
24712484 }
24722485
24732486 parser -> parsed_bytes += parser -> state .cursor - initial_cursor ;
24742487 parser -> incomplete_bytes = parser -> complete ? 0 : parser -> state .end - parser -> state .cursor ;
2475-
24762488 parser -> in_use = false;
2489+
24772490 if (status ) {
24782491 rb_jump_tag (status ); // reraise
24792492 }
0 commit comments