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
- Initialize the
SharePoint Client against a SharePoint Online site.
- 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.
- 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
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 aterror.message.value.However,
GetErrorDescription(in the SharePoint request helper codeunit) parses a root-levelerror_descriptionfield. That field belongs to the OAuth token error format, not to the OData verbose error format the same module guarantees by sendingodata=verbose.Consequently, for any real REST error (e.g. a
400 Bad Requestreturned by SharePoint), no message is extracted:Diagnostics.ErrorMessageand any surfaced error end up empty, which makes failures effectively non-diagnosable for consumers of the module.Expected behavior
Expected behavior
GetErrorDescriptionshould extract the message from the OData verbose structure that SharePoint actually returns, i.e.error.message.value(and ideally also exposeerror.code).Actual behavior
GetErrorDescriptionlooks only forerror_descriptionat 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
SharePoint Clientagainst a SharePoint Online site.400 Bad Request.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, notOData-Version):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. ..." } } }GetErrorDescriptionreturns an empty string for this body because it only checks forerror_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):Affected code
src/System Application/App/SharePoint)GetErrorDescriptionin the SharePoint request helper codeunit (the same codeunit that contains PrepareRequestMsg, which setsAccept: application/json;odata=verbose`).Environment
I will provide a fix for a bug