From 4c4803966e85a4b527d2595ea02754ebacf9eb90 Mon Sep 17 00:00:00 2001 From: prql-bot <107324867+prql-bot@users.noreply.github.com> Date: Tue, 26 May 2026 07:41:16 +0000 Subject: [PATCH] fix(dotnet): correct ArgumentException constructor usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The five `string.IsNullOrEmpty` guards in PrqlCompiler.cs threw `new ArgumentException(nameof(prqlQuery))`, passing the parameter name into the message slot. The result was an ArgumentException with `Message == "prqlQuery"` and `ParamName == null` — the opposite of what the call looked like it intended. Replace each guard with `ArgumentException.ThrowIfNullOrEmpty(...)`, which matches the modern style of the adjacent `ArgumentNullException.ThrowIfNull(options)` calls and sets ParamName correctly. Add regression tests asserting ParamName on each entry point; these would have caught the bug because the previous code left ParamName null. Co-Authored-By: Claude Opus 4.7 --- .../dotnet/PrqlCompiler.Tests/CompilerTest.cs | 32 +++++++++++++++++++ .../dotnet/PrqlCompiler/PrqlCompiler.cs | 27 +++------------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/prqlc/bindings/dotnet/PrqlCompiler.Tests/CompilerTest.cs b/prqlc/bindings/dotnet/PrqlCompiler.Tests/CompilerTest.cs index 6cada95f53cc..4ba64ec95717 100644 --- a/prqlc/bindings/dotnet/PrqlCompiler.Tests/CompilerTest.cs +++ b/prqlc/bindings/dotnet/PrqlCompiler.Tests/CompilerTest.cs @@ -57,6 +57,38 @@ public void RqToSql_ThrowsArgumentNullException_WhenOptionsNull() Assert.Throws(() => PrqlCompiler.RqToSql("{}", null!)); } + [Fact] + public void Compile_ThrowsArgumentException_WhenQueryIsEmpty() + { + // Regression: previously `new ArgumentException(nameof(prqlQuery))` + // passed the parameter name into the message slot, leaving ParamName + // unset and the exception message as just "prqlQuery". + var ex = Assert.Throws(() => PrqlCompiler.Compile("")); + Assert.Equal("prqlQuery", ex.ParamName); + } + + [Fact] + public void PrqlToPl_ThrowsArgumentException_WhenQueryIsEmpty() + { + var ex = Assert.Throws(() => PrqlCompiler.PrqlToPl("")); + Assert.Equal("prqlQuery", ex.ParamName); + } + + [Fact] + public void PlToRq_ThrowsArgumentException_WhenJsonIsEmpty() + { + var ex = Assert.Throws(() => PrqlCompiler.PlToRq("")); + Assert.Equal("plJson", ex.ParamName); + } + + [Fact] + public void RqToSql_ThrowsArgumentException_WhenJsonIsEmpty() + { + var ex = Assert.Throws( + () => PrqlCompiler.RqToSql("", new PrqlCompilerOptions())); + Assert.Equal("rqJson", ex.ParamName); + } + [Fact] public void Compile_HandlesNonAsciiInput() { diff --git a/prqlc/bindings/dotnet/PrqlCompiler/PrqlCompiler.cs b/prqlc/bindings/dotnet/PrqlCompiler/PrqlCompiler.cs index ac70a7df5895..dc27544d9faa 100644 --- a/prqlc/bindings/dotnet/PrqlCompiler/PrqlCompiler.cs +++ b/prqlc/bindings/dotnet/PrqlCompiler/PrqlCompiler.cs @@ -18,10 +18,7 @@ public static partial class PrqlCompiler /// cannot be compiled. public static Result Compile(string prqlQuery) { - if (string.IsNullOrEmpty(prqlQuery)) - { - throw new ArgumentException(nameof(prqlQuery)); - } + ArgumentException.ThrowIfNullOrEmpty(prqlQuery); return Compile(prqlQuery, new PrqlCompilerOptions()); } @@ -37,11 +34,7 @@ public static Result Compile(string prqlQuery) /// cannot be compiled. public static Result Compile(string prqlQuery, PrqlCompilerOptions options) { - if (string.IsNullOrEmpty(prqlQuery)) - { - throw new ArgumentException(nameof(prqlQuery)); - } - + ArgumentException.ThrowIfNullOrEmpty(prqlQuery); ArgumentNullException.ThrowIfNull(options); var targetPtr = options.Target is null @@ -72,10 +65,7 @@ public static Result Compile(string prqlQuery, PrqlCompilerOptions options) /// https://docs.rs/prqlc/latest/ public static Result PrqlToPl(string prqlQuery) { - if (string.IsNullOrEmpty(prqlQuery)) - { - throw new ArgumentException(nameof(prqlQuery)); - } + ArgumentException.ThrowIfNullOrEmpty(prqlQuery); var nativeResult = PrqlToPlExtern(prqlQuery); return new Result(nativeResult); @@ -91,10 +81,7 @@ public static Result PrqlToPl(string prqlQuery) /// https://docs.rs/prqlc/latest/ public static Result PlToRq(string plJson) { - if (string.IsNullOrEmpty(plJson)) - { - throw new ArgumentException(nameof(plJson)); - } + ArgumentException.ThrowIfNullOrEmpty(plJson); var nativeResult = PlToRqExtern(plJson); return new Result(nativeResult); @@ -112,11 +99,7 @@ public static Result PlToRq(string plJson) /// https://docs.rs/prqlc/latest/ public static Result RqToSql(string rqJson, PrqlCompilerOptions options) { - if (string.IsNullOrEmpty(rqJson)) - { - throw new ArgumentException(nameof(rqJson)); - } - + ArgumentException.ThrowIfNullOrEmpty(rqJson); ArgumentNullException.ThrowIfNull(options); var targetPtr = options.Target is null