Announcement

Collapse
No announcement yet.

Returning custom error text via API

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Returning custom error text via API

    I'm trying to return error messages to a custom client via API. However, none of the exception classes pass a custom error message or code to an API client via the response object. Here are the things I've tried:

    Generic exception with a custom message and one of the supported code options (note the statusText and responseText in the API response - it doesn't match the error text in the log):
    Code:
    Code:
      throw new \Exception("Test error", 400);
    
    Log:
      Espo.ERROR: API [POST]:/:controller/action/:action, Params:Array (     [controller] => timesheet     [action] => TimesheetData ) , InputData: {} - Test error [] []
      Espo.ERROR: Display Error: Test error, Code: 400 URL: /api/v1/timesheet/action/TimesheetData?timesheetId=5c1acb1a4f61b00ef [] []
    
    API Object Values:
      response: ""
      responseText: ""
      responseType: ""
      responseURL: "https://crm.pseglobal.com/api/v1/timesheet/action/TimesheetData?timesheetId=5c1acb1a4f61b00ef"
      responseXML: null
      status: 400
      statusText: "Bad Request"
    Generic exception with a custom message and a custom code option (note the E_NOTICE line, which is because 427 isn't in the list of choices in application/Espo/Core/Utils/Api/Output.php):
    Code:
    Code:
      throw new \Exception("Test error", 427);
    
    Log:
      Espo.ERROR: API [POST]:/:controller/action/:action, Params:Array (     [controller] => timesheet     [action] => TimesheetData ) , InputData: {} - Test error [] []
      Espo.ERROR: Display Error: Test error, Code: 427 URL: /api/v1/timesheet/action/TimesheetData?timesheetId=5c1acb1a4f61b00ef [] []
      Espo.NOTICE: E_NOTICE: Undefined offset: 1  []
    
    API Object Values:
      response: ""
      responseText: ""
      responseType: ""
      responseURL: "https://crm.pseglobal.com/api/v1/timesheet/action/TimesheetData?timesheetId=5c1acb1a4f61b00ef"
      responseXML: null
      status: 401
      statusText: "Unauthorized"
    Here are the choices mentioned above:
    Code:
    protected $errorDesc = array(
        400 => 'Bad Request',
        401 => 'Unauthorized',
        403 => 'Forbidden',
        404 => 'Page Not Found',
        409 => 'Conflict',
        500 => 'Internal Server Error',
    );
    There needs to be a generic exception class that passes messages and codes via the API because that is a requirement for pretty much any custom client application. How do I pass a message to my web browser using an exception in EspoCRM? Does it require a custom class and, if so, where should it be located?

  • #2
    I found that throwing an error returns the text, but not in the way I expected. It puts the text in the X-Status-Reason header, which is more complex to get out of the api. I had to update my .htaccess file in api/v1 to include the X-Status-Reason line:
    Code:
      1 <ifModule mod_headers.c>
      2   Header always set Access-Control-Allow-Methods "POST, GET, PUT, PATCH, DELETE"
      3   Header always set Access-Control-Expose-Headers: X-Status-Reason
      4 </ifModule>
      5 
      6 RewriteEngine On
      7 
      8 # Some hosts may require you to use the `RewriteBase` directive.
      9 # If you need to use the `RewriteBase` directive, it should be the
     10 # absolute physical path to the directory that contains this htaccess file.
     11 #
     12 # RewriteBase /
     13 
     14 RewriteRule .* - [E=HTTP_ESPO_CGI_AUTH:%{HTTP:Authorization}]
     15 
     16 RewriteCond %{REQUEST_FILENAME} !-f
     17 RewriteRule ^ index.php [QSA,L]
    Then I was able to parse it from an AJAX response:

    Code:
    let statusReason = xhr.getResponseHeader("X-Status-Reason");
    This is not a good solution. It should be easier.

    Comment

    Working...
    X