Status Codes & Errors¶
HTTP Status Codes¶
The OnSite API uses conventional HTTP response codes to indicate the success or failure of an API request.
Status Code | Message |
---|---|
200 | OK. The request has succeeded.
|
201 | Created. The request has been fulfilled and a new resource was created.
|
400 | Bad Request. The request could not be understood by the server. This can
occur if:
* The syntax of the XML object is incorrect
* The XML object contains read-only information
* The XML object is being written to the wrong URL
|
401 | Unauthorized. The request requires user authentication. May occur if
one or more of the following are missing or incorrect in the request
object:
* App ID (in the User-Agent header)
* Private ID (in the X-PAPPID header)
* Lightspeed username or password (in the Authorization header)
Or if the API Application is not licensed to the server (see
|
403 | Forbidden. The server understood the request, but is refusing to fulfill
it. May occur if there are no more user-seats available to connect to the
LightSpeed Server (see the note in Authentication); if you
attempt a POST/PUT/UNLOCK/LOCK call using a read-only application; or the
url is malformed.
|
404 | Not Found. The server has not found anything matching the URL.
|
405 | Method Not Allowed. Normally occurs when attempting a POST/PUT/UNLOCK/LOCK
on a resource that doesn’t support it.
|
406 | Not Acceptable. Normally occurs when there’s something incorrect about the
request, for instance, when attempting a PUT request on an Invoice whose
Posted flag is set to TRUE (you cannot edit a posted invoice. It must be
unposted first).
|
500 | Internal Server Error. Something went wrong with the OnSite API.
|
Error Response¶
Errors with the OnSite API are accompanied by an XML object documenting what went wrong.
<error class="lscore.errors.lightspeed_errors.ExampleError" type="server.lightspeederror">
<localizable_message type="server.example_error">
<fields>
<field name="some_property">4</field>
<field name="some_other_property">bar</field>
</fields>
<plain_message>This is an example error message.</plain_message>
</localizable_message>
<traceback/>
</error>
When parsing, the class
attribute in the root error
element is the identifier for the error,
and the plain_message
contains the human-readable string explaining the error. The traceback is
for debugging purposes by the OnSite API developers.
The localizable message’s type and fields can be utilized by the developer to localize or make
custom error messages. For localization, the plain_message
contains the English-language string
associated with the type to translate. The field
elements have the attribute name
that identify
the information contained inside the element.
Authentication Errors¶
There are three headers in a request for authenticating. The Private ID is included in the X-PAPPID header, the App ID is included in the User-Agent header, and the Lightspeed username and password are encoded in the Authorization header.
When the X-PAPPID or User-Agent header are incorrect, because the App ID or Private ID are incorrect, the following response is generated:
<error class="lsserver.auth.auth_service.InvalidUserAgent" type="auth.invalid_user_agent">
<localizable_message type="auth.unsupported_client_version">
<fields/>
<plain_message>Unsupported client version. Please upgrade you client install.</plain_message>
</localizable_message>
<traceback/>
</error>
When the Lightspeed username or password is incorrect, the following response is returned:
<error class="lscore.errors.server_errors.Unauthorized" type="server.unauthorized">
<localizable_message type="server.unauthorized">
<fields>
<field name="message">None</field>
</fields>
<plain_message>Unauthorized Request: None</plain_message>
</localizable_message>
<traceback/>
</error>
Validation Errors¶
When requests include a POST or PUT payload, the contents of that payload is first passed by a validator. At first there’s a check to see that the XML is valid. If it is not, an error akin to the following might be produced:
<error class="lscore.errors.lightspeed_errors.LightSpeedError" type="server.lightspeederror">
<localizable_message type="server.lightspeederror">
<fields/>
<plain_message>An unexpected error occurred.</plain_message>
</localizable_message>
<traceback>Traceback (most recent call last):
File "core/src/lscore/rest/request_handling.py", line 743, in new_f
res = callable(self, *args, **kwargs)
File "core/src/lscore/rest/request_handling.py", line 677, in new_f
response = callable(self, *new_args, **new_kwargs)
File "core/src/lscore/rest/framework.py", line 583, in post
return create(request, response, False, **kwargs)
File "core/src/lscore/rest/framework.py", line 551, in create
resource_data.root = creator.validate_create(resource_data)
File "source/src/lsserver/rest/standard_impl.py", line 203, in validate_create
return resource_data.request.request_as_xml(self.__validation_schema)
File "core/src/lscore/rest/request_handling.py", line 167, in request_as_xml
root = etree.fromstring(payload_xml)
File "lxml.etree.pyx", line 3032, in lxml.etree.fromstring (src/lxml/lxml.etree.c:68121)
File "parser.pxi", line 1786, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:102470)
File "parser.pxi", line 1674, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:101299)
File "parser.pxi", line 1074, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:96481)
File "parser.pxi", line 582, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:91290)
File "parser.pxi", line 683, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:92476)
File "parser.pxi", line 622, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:91772)
XMLSyntaxError: AttValue: " or ' expected, line 2, column 14
</traceback>
</error>
Then the validator checks to see that all the fields are properly entered. If this fails due to a missing element or whatnot, the OnSite API can spit out an error akin to the following:
<error class="lscore.rest.request_handling.ValidationError" type="resource.validation_error">
<localizable_message type="resource.validation_error">
<fields>
<field name="error_message">Expecting an element product, got nothing, line 1
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_NOELEM: Expecting an element product, got nothing
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_INTERSEQ: Invalid sequence in interleave
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_CONTENTVALID: Element gift_card failed to validate content</field>
</fields>
<plain_message>Unable to validate xml:
Expecting an element product, got nothing, line 1
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_NOELEM: Expecting an element product, got nothing
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_INTERSEQ: Invalid sequence in interleave
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_CONTENTVALID: Element gift_card failed to
validate content</plain_message>
</localizable_message>
<traceback>Traceback (most recent call last):
File "core/src/lscore/rest/request_handling.py", line 743, in new_f
res = callable(self, *args, **kwargs)
File "core/src/lscore/rest/request_handling.py", line 677, in new_f
response = callable(self, *new_args, **new_kwargs)
File "core/src/lscore/rest/framework.py", line 583, in post
return create(request, response, False, **kwargs)
File "core/src/lscore/rest/framework.py", line 551, in create
resource_data.root = creator.validate_create(resource_data)
File "source/src/lsserver/rest/standard_impl.py", line 203, in validate_create
return resource_data.request.request_as_xml(self.__validation_schema)
File "core/src/lscore/rest/request_handling.py", line 169, in request_as_xml
_Validator.validate(schema, root)
File "core/src/lscore/rest/request_handling.py", line 88, in validate
self.raise_rng_error(error)
File "core/src/lscore/rest/request_handling.py", line 114, in raise_rng_error
raise ValidationError(str(rng_error) + '\n\n' + str(rng_error.error_log))
ValidationError: Unable to validate xml:
Expecting an element product, got nothing, line 1
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_NOELEM: Expecting an element product, got nothing
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_INTERSEQ: Invalid sequence in interleave
<string>:1:0:ERROR:RELAXNGV:RELAXNG_ERR_CONTENTVALID: Element gift_card failed to validate content
</traceback>
</error>
Locked Resource Error¶
Resources in the Onsite API can be locked, preventing other users from updating resources at the same time. See Locking & Unlocking Resources for more information. If you send a request that requires a lock, but do not do so, the following error may occur:
<error class="lscore.locking.errors.NotLockedError" type="resource.not_locked">
<localizable_message type="resource.not_locked">
<fields>
<field name="item_id">67</field>
<field name="lock_name">product</field>
</fields>
<plain_message>Acquire a lock on product with id 67 first</plain_message>
</localizable_message>
<traceback>Traceback (most recent call last):
File "core/src/lscore/rest/request_handling.py", line 743, in new_f
res = callable(self, *args, **kwargs)
File "core/src/lscore/rest/request_handling.py", line 677, in new_f
response = callable(self, *new_args, **new_kwargs)
File "core/src/lscore/rest/framework.py", line 583, in post
return create(request, response, False, **kwargs)
File "core/src/lscore/rest/framework.py", line 550, in create
with self.lock_gen( resource_data, creator.get_lockable(resource_data) ):
File "/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "core/src/lscore/rest/framework.py", line 183, in lock_gen
raise NotLockedError(lockable.name, lockable.id)
NotLockedError: Acquire a lock on product with id 67 first
</traceback>
</error>
When attempting to use a resource that’s already locked, an error like the following may occur:
<error class="lscore.locking.errors.NotYourLockError" type="resource.not_your_lock">
<localizable_message type="resource.not_your_lock">
<fields>
<field name="item_id">68</field>
<field name="lock_name">product</field>
<field name="current_lock_holder">lightspeed</field>
</fields>
<plain_message>product is in use by lightspeed. You will not be able to make changes until
lightspeed closes the document.</plain_message>
</localizable_message>
<traceback>Traceback (most recent call last):
File "core/src/lscore/rest/request_handling.py", line 695, in new_f
res = callable(self, request, response, *args, **kwargs)
File "core/src/lscore/rest/framework.py", line 780, in PUT
return self.update(request, response, True, *args)
File "core/src/lscore/rest/framework.py", line 768, in update
with self.lock_gen( resource_data, updater.get_lockable(resource_data) ):
File "/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "core/src/lscore/rest/framework.py", line 187, in lock_gen
lock.current_lock_holder.username)
NotYourLockError: product is in use by lightspeed.
You will not be able to make changes until lightspeed closes the document.
</traceback>
</error>
Note
This error can also occur if you locked the resource, but did not do the PUT
request as
part of the same session.
Other Errors¶
When the connection to the OnSite API fails without producing an error generated by the API, there are other things to watch for when debugging:
- An incompatible version of LightSpeed Server (Demo, 3.4.5 or lower)
- SSL certificate verification not disabled
- Incorrect Port number (should only be 9630 or 9631 in some cases, anything else will trigger the error)
- Blocked port (9630, 9631 are the ports that LightSpeed Server will use)
- Issue with IP address in URL (does not exist, blocked, etc)
- Attempt to acquire a substantially vast amount of data (ex. GET /api/products/ of a database with over 15K products)