Why Sketchup crashes when cancel Class: Sketchup::Http::Request


#1

I use Class: Sketchup::Http::Request to make a request to my cloud. The request looks like this

req = Sketchup::Http::Request.new( Constants::SiteURL, Sketchup::Http::POST)
req.start do |req, response|

end

But when I call

req.cancel

Sketchup crashes and shows me the bug report form and then closes.
What can be the reason of such kind of behavior?


#2

Check the official Issue Tracker on GitHub …

If you do not see an issue, please file a report with a reproducible code snippet.

My first thought is that your sample code is not using a persistent reference. Local references can go out of scope easily.


You might be interested in reading this issue …


#3

Where can I get an information about scope?
For example I try to cancel the request in set_upload_progress_callback method to see if it works.

req.set_upload_progress_callback do |current, total|
              req.cancel
end

But it crashes.
Is this a situation without persistent reference?


#4

It makes no sense to put a cancel call inside a loop without some kind of conditional expression.
Basically the first time through the loop the request would get cancelled.

You are using a local reference, ie: req

Since I cannot see all of your code, I cannot say. Is the code within a method ?

A persistent reference is an instance variable (@req,) or a class/module variable (@@req.)

From any good Ruby programming book. There are free ones available for download. See


#5

Thanks Dan, my code is within a class method

def self.setCallbacks
    @dialog.add_action_callback("Upload") { |action_context, value|
        req = Sketchup::Http::Request.new( Constants::SiteURL, Sketchup::Http::POST)

        req.set_upload_progress_callback do |current, total|
              req.cancel
        end
        
       req.start do |req, response|
       end

I think I have a req reference “alive” ?


#6

Perhaps not. Local references inside methods go out of scope when the method returns (ends), and Ruby’s automatic garbage collection will destroy objects that are no longer referenced.

I am unsure if the callback’s block object will preserve the local req reference inside it.

So try something like …

def self.setCallbacks
  @dialog.add_action_callback("Upload") { |action_context, value|
    @req = Sketchup::Http::Request.new( Constants::SiteURL, Sketchup::Http::POST)

    # load the file text into a reference to a String object
    @req.body= @some_file_text

    @req.set_upload_progress_callback do |current, total|
      if @req.status == Sketchup::Http::STATUS_FAILED
        puts "Upload Failed"
        @req.cancel
      elsif @req.status == Sketchup::Http::STATUS_CANCELED
        puts "Upload Canceled"
      else
        puts total
        if @req.status == Sketchup::Http::STATUS_SUCCESS
          puts "Upload Successful"
        end
      end
    end

    @req.start
  }
end

#7

I’ve tried to make req an instance field @req.
I also can see the value of @req.status it gets 2.
But after @req.cancel it again crashes.

@req.set_upload_progress_callback do |current, total|
                puts @req.status
                @req.cancel                  
end

Anyway thank you very much for help.


#8

Once again, you cannot have @req.cancel inside a progress callback block without a condition on it. It makes no sense.

Did you fill out the BugSplat! form and send it in ? Crash report number ?


It may be due to the fact that this is nested inside a web dialog callback block.

I do NOT get a crash with this code …

module CrashTest

  extend self

  def set_callbacks

    @req = Sketchup::Http::Request.new( "http://localhost", Sketchup::Http::POST)
    
    @req.body = "Some fake text."

    @req.set_upload_progress_callback do |current, total|
      puts "Canceling ..."
      @req.cancel
    end

    @req.start do |request, response|
      puts "Starting ..."
    end

  end
  
  def go
    set_callbacks()
  end

end

… but then again I do not see the progress callback block having executed.
(Perhaps the fake text is too small?)


#9

I know that it makes no sense but I think to solve the problem about the crash then add appropriate condition.I think it is not connected to the main problem.

Yes I have filled and sent it for several times, I also have mentioned an email address but I couldn’t find the report number(see the picture bellow)

I’ve moved the call of set_callbacks function out of the callback (immediately when I open the extension) but I could see the crash again.
I also examined that it crashes only during post requests, when the server also waits for the post request. In my case the controller action has [HttpPost] attribute, I use .Net so the main condition is there shouldn’t be any redirect I guess.
I also tried to post to this url. I know it also makes no sense, but in this situation I always get crash. please try this one to your end.

        def set_callbacks
           @req = Sketchup::Http::Request.new('https://www.microsoft.com/en-us/', Sketchup::Http::POST)
          
           @req.body = "Some fake text."
       
           @req.set_upload_progress_callback do |current, total|
             puts "Canceling ..."
             @req.cancel
             puts "after cancel"
           end
       
           @req.start do |request, response|
             puts "Starting ..."
             puts response.status_code 
           end

      end

About callback I have tried this code and could see the progress callback having executed

     def set_callbacks
           @req = Sketchup::Http::Request.new('http://localhost:1334/' + 'ClientDashboard/List', Sketchup::Http::GET) 
          
           @req.body = "Some fake text."
       
           @req.set_upload_progress_callback do |current, total|
             puts "Canceling ..."
             @req.cancel
             puts "after cancel"
           end
       
           @req.start do |request, response|
             puts "Starting ..."
             puts response.status_code 
           end

      end

and in ruby console I see

    Canceling ...
    Starting ...
    200
    after cancel

As you can see here I use Sketchup::Http::GET with @req.body = "Some fake text."
I don’t know whether this is correct or not, but it says that prrogress callback is executed.


#10

Can you provide a complete example that reproduce the crash? We could then hook it up to the debugger and see what is going on.

Edit: If you do, please open an issue in the issue tracker: https://github.com/SketchUp/api-issue-tracker/issues