Francesca Shiekh

Debugging APIs

Discussion created by Francesca Shiekh on Feb 16, 2015
Latest reply on Feb 20, 2015 by Steve Cox
I use Dan Kalish's script testApi.php found here:
API script does not return any data

to test and debug my custom APIs and it has been working fine so far (I've developed three APIs before this one all without issue).
I made a slight variant to the script to pass the api path as a variable at the top of the script so I can easily change what API I test. Other than that it's essentially the same as Dan's.

I am developing an API that zips all the attachments from a custom documents-type module and forces the download of the zip file. The "fatal" log entries are so I can follow the process to debug (debug mode includes too much stuff to filter through). I looked through FileTempApi.php and FileApi.php for clues, and that's where I found and included the rawReply and allowDownloadCookie in the def of the API: 
class downloadAttachmentsApi extends SugarApi{
  public function registerApiRest() {
    return array(
      'downloadAttachments' => array(
        'reqType' => 'GET',
        'path' => array('downloadAttachments', '?', '?', '?' ,'?','?'),
        'pathVars' => array('','document_module', 'module_name','module_id','all','selection'),
        'method' => 'downloadAttachments',
        'rawReply' => true,
        'allowDownloadCookie' => true,
        'shortHelp' => 'Custom WR. Downloads a Zip file with All or Selected attachments from document_module related to  module_name, module_id. all = true/false and if false provide the ids of the documents to be downloaded in the selection param as a list',
        'longHelp' => '',
  function downloadAttachments($api, $args)
  { <create zip file at $zip_path>
        $filepath = $zip_path;
          $GLOBALS['log']->fatal('prepare to download' .$filepath);
          $display_name = basename($zip_path);
          $filedata = getimagesize($filepath);
          $info = array(
            'content-type' => $filedata['mime'],
            'path' => $filepath,
          require_once "include/download_file.php";
          $dl = new DownloadFileApi($api);
          $dl->outputFile(true, $info);
            function () use($filepath) {
              if (is_file($filepath)) {
          throw new SugarApiException('Zip file not found');
        }  <some more exception handling from the zip create>    } }


the URL looks like this:


when I look at my registered API through the rest help at https://<myserver>/rest/v10/help

the API definition is there:

When I execute from TestApi.php I get nothing, no output, but the log entry is there and if I don't unlink($filepath) the zip file is there which makes me think there is a problem with forcing the download but the API works.

If I execute the same script from the API call inside the button definition however, I get an error "Could not find a route with 6 elements" yet it worked from the testApi.php.... why?

The API call from the button definition:

  downloadAll: function(){
    var subpanel_module = 'attch_Case_Attachments',
        module_name = this.context.parent.get('module'),
        module_id = this.context.parent.get('model').get('id'),
        selection = '0',
        all = true,
        url = app.api.buildURL('downloadAttachments/'+subpanel_module+'/'+module_name+'/'+module_id+'/true/'+selection);
    //make the api call'GET', url, null, {
      success: function (o){
        console.log('downloadAll '+o);
      error: function(o){"no-selection", {
          level: 'info',
          messages: 'Could not download files. Contact your Sugar Administrator',
          autoClose: 'false',
        console.log('downloadAll failed '+o);

The Console log shows the same path I pasted into the testApi.php:


ROWACTION https://<myserver>/sugarcrm/res...... 404 (Not Found)
downloadAll failed HTTP error: 404
type: error
error: Not Found
response: {"error":"no_method","error_message":"Could not find a route with 6 elements"}
code: no_method
message: Could not find a route with 6 elements

In the test it creates the file fine (though I still can't get it to download) which means the route is fine. So why would it not be found when called from within the javascript of the button?

Any hints as to how to better troubleshoot this would be greatly appreciated.


PS. did I mention we need a better way to post code on this community? It's extremely frustrating to try and post legible code...