CI: add dotnet --info / df -h / free -m diagnostics and an explicit 'Restore NuGet packages' step before build to isolate restore failures (build of e15f650 on main exited with code -1 and zero dotnet output). #5

Merged
gsadmin merged 27 commits from dev into main 2026-06-05 01:24:51 +00:00
7 changed files with 144 additions and 9 deletions
Showing only changes of commit 5e6364f9e0 - Show all commits
+2
View File
@@ -6,6 +6,8 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loos
## Unreleased
- Infisical API error responses are now parsed to surface the server-side `message`, `error`, and `reqId` fields. The 4xx/5xx exception message includes the human-readable explanation (e.g. "The project is of type secret-manager") instead of an opaque `Infisical API returned 400 (Bad Request)`. The `InfisicalApiException` gains `ApiErrorMessage` and `ApiRequestId` properties; `InfisicalErrorDetails` carries the same fields so PowerShell error records and logger output expose them.
## 2026.06.04.1920
- Build produced from commit 0f8f44afdb38.
@@ -0,0 +1,119 @@
using System;
using Newtonsoft.Json.Linq;
namespace PSInfisicalAPI.Errors
{
internal static class InfisicalApiErrorEnvelope
{
public static void Enrich(InfisicalApiException exception, string body)
{
if (exception == null || string.IsNullOrEmpty(body))
{
return;
}
string trimmed = body.TrimStart();
if (trimmed.Length == 0 || (trimmed[0] != '{' && trimmed[0] != '['))
{
return;
}
JObject obj;
try
{
JToken token = JToken.Parse(body);
if (token.Type != JTokenType.Object) { return; }
obj = (JObject)token;
}
catch (Exception)
{
return;
}
string message = ReadString(obj, "message");
string error = ReadString(obj, "error");
string reqId = ReadString(obj, "reqId");
if (!string.IsNullOrEmpty(message)) { exception.ApiErrorMessage = message; }
if (!string.IsNullOrEmpty(error) && string.IsNullOrEmpty(exception.ApiErrorCode)) { exception.ApiErrorCode = error; }
if (!string.IsNullOrEmpty(reqId)) { exception.ApiRequestId = reqId; }
}
public static string BuildExceptionMessage(int statusCode, string reasonPhrase, string body)
{
string baseMessage = string.Concat(
"Infisical API returned ",
statusCode.ToString(System.Globalization.CultureInfo.InvariantCulture),
" (", reasonPhrase ?? string.Empty, ").");
string apiMessage = null;
string apiError = null;
string reqId = null;
if (!string.IsNullOrEmpty(body))
{
string trimmed = body.TrimStart();
if (trimmed.Length > 0 && trimmed[0] == '{')
{
try
{
JToken token = JToken.Parse(body);
if (token.Type == JTokenType.Object)
{
JObject obj = (JObject)token;
apiMessage = ReadString(obj, "message");
apiError = ReadString(obj, "error");
reqId = ReadString(obj, "reqId");
}
}
catch (Exception)
{
}
}
}
if (string.IsNullOrEmpty(apiMessage) && string.IsNullOrEmpty(apiError) && string.IsNullOrEmpty(reqId))
{
return baseMessage;
}
System.Text.StringBuilder builder = new System.Text.StringBuilder(baseMessage);
if (!string.IsNullOrEmpty(apiMessage))
{
builder.Append(' ').Append(apiMessage);
}
if (!string.IsNullOrEmpty(apiError) || !string.IsNullOrEmpty(reqId))
{
builder.Append(" [");
bool needsSeparator = false;
if (!string.IsNullOrEmpty(apiError))
{
builder.Append("error=").Append(apiError);
needsSeparator = true;
}
if (!string.IsNullOrEmpty(reqId))
{
if (needsSeparator) { builder.Append("; "); }
builder.Append("reqId=").Append(reqId);
}
builder.Append(']');
}
return builder.ToString();
}
private static string ReadString(JObject obj, string name)
{
JToken token;
if (obj.TryGetValue(name, StringComparison.OrdinalIgnoreCase, out token) && token != null && token.Type == JTokenType.String)
{
return (string)token;
}
return null;
}
}
}
@@ -10,6 +10,8 @@ namespace PSInfisicalAPI.Errors
public int? StatusCode { get; set; }
public string ReasonPhrase { get; set; }
public string ApiErrorCode { get; set; }
public string ApiErrorMessage { get; set; }
public string ApiRequestId { get; set; }
public string SanitizedBody { get; set; }
public int? LineNumber { get; set; }
public int? LinePosition { get; set; }
@@ -26,6 +26,8 @@ namespace PSInfisicalAPI.Errors
details.StatusCode = apiException.StatusCode;
details.ReasonPhrase = apiException.ReasonPhrase;
details.ApiErrorCode = apiException.ApiErrorCode;
details.ApiErrorMessage = apiException.ApiErrorMessage;
details.ApiRequestId = apiException.ApiRequestId;
details.SanitizedBody = apiException.SanitizedBody;
details.EndpointName = apiException.EndpointName;
details.RequestMethod = apiException.RequestMethod;
@@ -70,6 +72,16 @@ namespace PSInfisicalAPI.Errors
logger.Error(Component, string.Concat("API Error Code: ", details.ApiErrorCode));
}
if (!string.IsNullOrEmpty(details.ApiErrorMessage))
{
logger.Error(Component, string.Concat("API Error Message: ", details.ApiErrorMessage));
}
if (!string.IsNullOrEmpty(details.ApiRequestId))
{
logger.Error(Component, string.Concat("API Request Id: ", details.ApiRequestId));
}
if (details.LineNumber.HasValue)
{
logger.Error(Component, string.Concat("Line: ", details.LineNumber.Value.ToString(CultureInfo.InvariantCulture)));
@@ -33,6 +33,8 @@ namespace PSInfisicalAPI.Errors
public int StatusCode { get; set; }
public string ReasonPhrase { get; set; }
public string ApiErrorCode { get; set; }
public string ApiErrorMessage { get; set; }
public string ApiRequestId { get; set; }
public string SanitizedBody { get; set; }
public string EndpointName { get; set; }
public string RequestMethod { get; set; }
@@ -135,15 +135,14 @@ namespace PSInfisicalAPI.Http
private static InfisicalApiException BuildApiException(InfisicalHttpResponse response, InfisicalEndpointDefinition definition)
{
InfisicalApiException exception = new InfisicalApiException(string.Concat(
"Infisical API returned ",
response.StatusCode.ToString(CultureInfo.InvariantCulture),
" (", response.ReasonPhrase ?? string.Empty, ")."));
string message = InfisicalApiErrorEnvelope.BuildExceptionMessage(response.StatusCode, response.ReasonPhrase, response.Body);
InfisicalApiException exception = new InfisicalApiException(message);
exception.StatusCode = response.StatusCode;
exception.ReasonPhrase = response.ReasonPhrase;
exception.EndpointName = definition.Name;
exception.RequestMethod = definition.Method;
exception.SanitizedBody = response.Body;
InfisicalApiErrorEnvelope.Enrich(exception, response.Body);
return exception;
}
}
@@ -625,15 +625,14 @@ namespace PSInfisicalAPI.Secrets
private static InfisicalApiException BuildApiException(InfisicalHttpResponse response, InfisicalEndpointDefinition definition)
{
InfisicalApiException exception = new InfisicalApiException(string.Concat(
"Infisical API returned ",
response.StatusCode.ToString(CultureInfo.InvariantCulture),
" (", response.ReasonPhrase ?? string.Empty, ")."));
string message = InfisicalApiErrorEnvelope.BuildExceptionMessage(response.StatusCode, response.ReasonPhrase, response.Body);
InfisicalApiException exception = new InfisicalApiException(message);
exception.StatusCode = response.StatusCode;
exception.ReasonPhrase = response.ReasonPhrase;
exception.EndpointName = definition.Name;
exception.RequestMethod = definition.Method;
exception.SanitizedBody = response.Body;
InfisicalApiErrorEnvelope.Enrich(exception, response.Body);
return exception;
}