Sonos Music API - Getting Started Guide

Error handling

SOAP uses <Fault> elements to return errors for failed requests. Your music service should always return HTTP status code values of 500 Internal Server Error with any SOAP fault it throws regardless of the cause of the error. The SOAP envelope included in the HTTP body should consist solely of a SOAP <body> element containing a SOAP <Fault> element in place of the standard SOAP body format for the call. No other content should be included in the body. 

The <Fault> element consists of the following sub-elements:

  • <faultcode> (Required) Contains a string identifying the error.
  • <faultstring> (Required) Contains a human-readable description of the error.
  • <faultactor> (Not used) Contains information about the cause of the error, but is ignored by SMAPI.
  • <detail> (Optional) Provides additional detail about the error in any format according to the SOAP specification.

The expected syntax for the <Fault> element is:

<[soap]:Fault>
  <faultcode>[errorCode]</faultcode>
  <faultstring>[errorDescription]</faultstring>
  <detail>[errorDetails]</detail>
</[soap]:Fault>

The expectations for these values within Sonos are described in the sections below.

Fault Codes

The <faultcode> element contains a defined fault code indicating the type of error encountered. Sonos defines about a dozen predefined codes your music service should use. SOAP defines several types of errors of which Sonos uses two: Client and Server. Server errors within SMAPI typically indicate an issue with your music service such as a planned outage and are also used for the default error case when none of the other defined fault codes fits the situation (even if the problem is clearly not in your music service). Client errors indicate that the server is operational but a particular request cannot be fulfilled for one of the defined reasons. Some of the reasons to throw a Client error include problems authenticating a user, users trying to access functionality not available to their account type or location, and incorrect or invalid ID values that do not map to valid items in the music service.

The format of the <faultcode> element is as follows:

[errorType].[codeString]

The [errorType] is either Client or Server and [codeString] is the actual error code.

Sonos supports the following fault codes:

Type Fault Code Meaning
Server ServiceUnavailable The server is temporarily unavailable. Typically this is thrown for a planned outage or when the reason for an unplanned outage is understood and the service has enough connectivity to return a response.
Server ServiceUnknownError An unknown error occurred. This is the default error for most services and is thrown for any error without a specific alternate exception defined.
Client AuthTokenExpired The request has an invalid token. The most likely reason for this error is an expired token. See the refreshing expired authentication tokens section of processing authentication credentials for API requests.
Client DeviceCertExpired The provided device certificate has expired.
Client DeviceCertInvalid The provided device certificate is invalid.
Client DeviceCertRequired A required device certificate was not provided.
Client DeviceCertRevoked The provided device certificate is revoked by the service.
Client DeviceLimit This user account has reached the limit for concurrent account use with your service.
Client ItemNotFound The requested item does not exist. If the correct ID was sent by the request, the related item may have been deleted via a different client.
Client LoginDisabled The user’s account has been disabled.
Client LoginInvalid The username/password combination was invalid.
Client LoginUnauthorized The user’s account can no longer be used on Sonos. This should be sent if a trial account expired.
Client LoginUnsupported The user’s account cannot be used on Sonos or with the specified feature. This should be sent if you require a specific service tier to use Sonos or to use specific features and the requesting user's account is on a different service tier.
Client  NOT_LINKED_RETRY  The user account is not linked to the supplied link code but is linkable. This error is only used as part of the DeviceLink authentication process and is not user visible in any way. See getDeviceAuthToken for details.
Client NOT_LINKED_FAILURE The user account cannot be linked to the supplied code or the code is invalid. This indicates a permanent failure. Sonos mus request a new link code for the user. This error is only used as part of the DeviceLink authentication process and is not user visible in any way. See getDeviceAuthToken for details.
Client SessionIdInvalid The supplied session ID is invalid or has expired. We recommend that you no longer use getSessionId.
Client TokenRefreshRequired The token has expired but can be refreshed. This error must include a <detail> element containing a new token and a new refresh token for the user. No error message is displayed to the user but the supplied new token replaces the existing token information for the user cached in the controller.
Client UnsupportedTerritory The request is coming from outside the geographic range supported by your service according to whatever means you use to determine user location (registered location of the user, geographic location of the IP address, etc.). If using session-based authentication, the getSessionId call will return this error when applicable. If using DeviceLink authentication, it will not be returned until the first call that uses an established authentication token. Calls to getDeviceLinkCode and getDeviceAuthToken will succeed whether or not any geographic constraints are met.

 

Logging

Sonos logs all errors thrown by your music service. Errors that happen while actively streaming music are logged in the player; all other errors including errors while setting up accounts, logging in, browsing, or searching are logged in the controller. In addition to the fault code, the contents of the <faultstring> element are stored in the log for future reference. The <faultstring> element should contain a human readable description of the error as well as any information you find helpful for debugging cases when the error is thrown. These logs can then be accessed using diagnostic programs if necessary for troubleshooting.

Desktop controller logs will also feed into the Mac OS X Console viewer or can be found as XML files on Windows at [systemdrive]:\programdata\Sonos,_Inc\runtime (where [systemdrive] is your main system drive, typically c). Note that this is a hidden directory and also that you will need to add a pair of matching opening and closing elements to these files to view them in an XML viewer (any element name is fine; <foo> at the start of the file and </foo> at its end will work).

Default Error Messages

Sonos uses the fault code you return and the current state of the controller to determine the error message to show users when an error is thrown. Default text is defined for each of the supported fault codes in several applicable situations such as setting up your music service, browsing music, or streaming music.

For instance, suppose a user had a trial account for your music service that just expired. Sonos still has a valid authentication token for the user and sends a request to browse your service using that token. The request should result in a Client.LoginUnauthorized fault and the following error message will display to the user:

Unable to browse music - your [serviceName] trial has expired.

The [serviceName] is the name of your music service.

On the back-end, the following request was made by the controller to your service:

POST http://musicservice.example.com
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://www.sonos.com/Services/1.1#getMetadata"
Host: example.com
 
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http://www.sonos.com/Services/1.1">
   <soap:Header>
      <ns:credentials>
         <ns:deviceId>device1</ns:deviceId>
         <ns:deviceProvider>Sonos</ns:deviceProvider>
         <ns:loginToken>
            <ns:token>authtoken</ns:token>
            <ns:key>refreshtoken</ns:key>
            <ns:householdId>house1</ns:householdId>
         </ns:loginToken>
      </ns:credentials>
   </soap:Header>
   <soap:Body>
      <ns:getMetadata>
         <ns:id>albums-album123</ns:id>
         <ns:index>0</ns:index>
         <ns:count>10</ns:count>
      </ns:getMetadata>
   </soap:Body>
</soap:Envelope>

And you should send the following response:

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf8;
Content-Length: 320
 
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
      <soap:Fault>
         <faultcode>Client.LoginUnauthorized</faultcode>
         <faultstring>Trial account has expired</faultstring>
      </soap:Fault>
</soap:Body>
</soap:Envelope>

Note that the HTTP status code returned is 500 even though the fault code is classified as a client error.

Custom Error Messages

You must use one of the defined fault codes for all error messages, but you may supply a custom error message instead of using the default error message associated with that fault code. Sonos allows you to override any default error message, but please exercise caution if you choose to override messages that direct users to action. For example, think carefully before changing the error message that tells users to reauthenticate with your service when necessary.

Custom error messages are specified using the detail element of a SOAP fault by including two sub-elements: <ExceptionInfo> and <SonosError>:

  • <ExceptionInfo> Contains additional logging information specific to your error. Its contents are logged alongside the contents of the <faultcode> and <faultstring> elements and available for debugging issues, should they arise.
  • <SonosError> Contains a numeric code between 0 and 999. Each code maps to an entry in your application’s string table with a stringId of Error[sonosErrorValue]Message containing the actual error message. Messages have a limit of 125 characters and must be provided in each of the languages supported by Sonos.

The expected syntax for the detail element is:

<detail>
  <[ns]:ExceptionInfo>[logMessage]</[ns]:ExceptionInfo>
  <[ns]:SonosError>[sonosErrorValue]</[ns]:SonosError>
</detail>

The [logMessage] is a string placed into the error logs and [sonosErrorValue] is the numerical key to the error message stored in the string tables.

For example, suppose your service restricts rating songs to premium members. When a member with a free account tries to rate a song, he might get the following error:

Rating is only available to premium members.

The underlying rateItem call might return the following response:

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf8;
Content-Length: 360
 
<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http://www.sonos.com/Services/1.1">
   <soap:Body>
       <soap:Fault>
           <faultcode>Client.LoginUnsupported</faultcode>
           <faultstring>Unsupported action for account type
           </faultstring>
           <detail>
              <ns:ExceptionInfo>Feature Unsupported for User Type
              </ns:ExceptionInfo>
              <ns:SonosError>27</ns:SonosError>
           </detail>
       </soap:Fault>
   </soap:Body>
</soap:Envelope>

And the string table will include the following entries:

<stringtables xmlns="http://sonos.com/sonosapi">
  <stringtable rev="6" xml:lang="en-US">
    ...
    <string stringId="Error27Message">Rating is only available to premium members.</string>
    ...
  </stringtable>
  <stringtable rev="6" xml:lang="de-DE">
    ...
    <string stringId="Error27Message">Bewertung ist nur fur Premium Mitglieder verfugbar.</string>
    ...
  </stringtable>
  ...
</stringtables>

If for some reason your string table does not have the required messages, the user will get an error message indicating something went wrong and they should retry. If the issue is not temporary, this could result in a loop until the user gives up.

Token Refresh Response

When your service determines the authentication token has expired, it should throw a Client.TokenRefreshRequired error. This uses the <detail> element to return a new user authorization token and refresh key that will replace the expired token and key in the controller cache. In this case the element contains a completely different structure compared to the structure defined above for returning custom error messages. For specific information about this format see the section on refreshing tokens in processing authentication credentials for API requests.