Skip to content

[Bug]: SharePoint Client returns empty error messages (GetErrorDescription parses 'error_description' instead of OData verbose 'error.message.value') #8476

@glachana

Description

@glachana

Describe the issue

The SharePoint module's request helper always sends the request header Accept: application/json;odata=verbose. As a result, the SharePoint REST (_api/...) service returns error responses in OData v3 verbose format, where the human-readable message is located at error.message.value.

However, GetErrorDescription (in the SharePoint request helper codeunit) parses a root-level error_description field. That field belongs to the OAuth token error format, not to the OData verbose error format the same module guarantees by sending odata=verbose.

Consequently, for any real REST error (e.g. a 400 Bad Request returned by SharePoint), no message is extracted: Diagnostics.ErrorMessage and any surfaced error end up empty, which makes failures effectively non-diagnosable for consumers of the module.

Expected behavior

Expected behavior

GetErrorDescription should extract the message from the OData verbose structure that SharePoint actually returns, i.e. error.message.value (and ideally also expose error.code).

Actual behavior

GetErrorDescription looks only for error_description at the root of the JSON body. Since that key never exists in OData verbose error responses, the returned description is always empty for genuine REST errors.

Steps to reproduce

  1. Initialize the SharePoint Client against a SharePoint Online site.
  2. Trigger a request that the server rejects with a business error — e.g. upload a file whose name already exists with overwrite disabled, so SharePoint returns 400 Bad Request.
  3. Inspect GetDiagnostics().GetErrorMessage() (or the surfaced error).

Result: the error message is empty, even though the HTTP body contains a clear description.

Additional context

Evidence

Response headers confirm the service speaks OData v3 (note DataServiceVersion, not OData-Version):

HTTP/1.1 400 Bad Request
DATASERVICEVERSION: 3.0
MicrosoftSharePointTeamServices: 16.0.0.27320
SPRequestGuid: <correlation-guid>

Response body (OData v3 verbose), redacted:

{
  "error": {
    "code": "-2130575257, Microsoft.SharePoint.SPException",
    "message": {
      "lang": "fr-FR",
      "value": "A file with the name <redacted-path>.csv already exists. ..."
    }
  }
}

GetErrorDescription returns an empty string for this body because it only checks for error_description.

Proposed fix

Parse the OData verbose structure, with a tolerant fallback so the procedure also handles the OAuth-style body and an eventual plain-string message (OData v4 shape):

local procedure GetErrorDescription(): Text
var
    Result: Text;
    JObject: JsonObject;
    JError: JsonObject;
    JToken: JsonToken;
    JMessageToken: JsonToken;
begin
    GetResultAsText(Result);
    if Result = '' then
        exit;
    if not JObject.ReadFrom(Result) then
        exit(Result);

    // OData verbose: error.message.value (or error.message as a plain string)
    if JObject.Get('error', JToken) then begin
        if JToken.IsObject() then begin
            JError := JToken.AsObject();
            if JError.Get('message', JMessageToken) then begin
                if JMessageToken.IsObject() then begin
                    if JMessageToken.AsObject().Get('value', JToken) then
                        exit(JToken.AsValue().AsText());
                end else
                    if JMessageToken.IsValue() then
                        exit(JMessageToken.AsValue().AsText());
            end;
        end else
            // OAuth: { "error": "invalid_grant", "error_description": "..." }
            if JToken.IsValue() and JObject.Get('error_description', JToken) then
                exit(JToken.AsValue().AsText());
    end;

    // Fallback: OAuth error_description at root
    if JObject.Get('error_description', JToken) then
        exit(JToken.AsValue().AsText());

    exit(Result);
end;

Affected code

  • Module: System Application — SharePoint (src/System Application/App/SharePoint)
  • Procedure: GetErrorDescription in the SharePoint request helper codeunit (the same codeunit that contains PrepareRequestMsg, which sets Accept: application/json;odata=verbose`).

Environment

  • Business Central version: 28.0 (FR)
  • Platform: 28.0.50706.0
  • Application: 28.0.46665.50875
  • Environment type: Sandbox (FR_Develop)
  • SharePoint: SharePoint Online (MicrosoftSharePointTeamServices 16.0.0.27320)
  • I will provide a fix for a bug

I will provide a fix for a bug

  • I will provide a fix for a bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    IntegrationGitHub request for Integration area

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions