Skip to content

Commit 9e0346b

Browse files
Copilotwcandillon
andcommitted
Fix GPUError message storage by using std::string instead of char const *
Co-authored-by: wcandillon <306134+wcandillon@users.noreply.github.com>
1 parent 3118ec7 commit 9e0346b

4 files changed

Lines changed: 80 additions & 7 deletions

File tree

packages/webgpu/cpp/rnwgpu/api/GPU.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ GPU::requestAdapter(
5050
std::unordered_set<std::string> GPU::getWgslLanguageFeatures() {
5151
wgpu::SupportedWGSLLanguageFeatures supportedFeatures = {};
5252
_instance.GetWGSLLanguageFeatures(&supportedFeatures);
53-
53+
5454
std::unordered_set<std::string> result;
5555
for (size_t i = 0; i < supportedFeatures.featureCount; i++) {
5656
wgpu::WGSLLanguageFeatureName feature = supportedFeatures.features[i];

packages/webgpu/cpp/rnwgpu/api/GPUError.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <memory>
4+
#include <string>
45

56
#include "webgpu/webgpu_cpp.h"
67

@@ -13,10 +14,10 @@ class GPUError {
1314

1415
public:
1516
GPUError(wgpu::ErrorType aType, char const *aMessage)
16-
: type(aType), message(aMessage) {}
17+
: type(aType), message(aMessage ? aMessage : "") {}
1718

1819
wgpu::ErrorType type;
19-
char const *message;
20+
std::string message;
2021
};
2122

2223
} // namespace rnwgpu
@@ -33,8 +34,9 @@ template <> struct JSIConverter<std::shared_ptr<rnwgpu::GPUError>> {
3334
static jsi::Value toJSI(jsi::Runtime &runtime,
3435
std::shared_ptr<rnwgpu::GPUError> arg) {
3536
jsi::Object result(runtime);
36-
result.setProperty(runtime, "message",
37-
jsi::String::createFromUtf8(runtime, arg->message));
37+
result.setProperty(
38+
runtime, "message",
39+
jsi::String::createFromUtf8(runtime, arg->message.c_str()));
3840
return result;
3941
}
4042
};

packages/webgpu/cpp/rnwgpu/api/descriptors/Unions.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,8 @@ static void convertJSUnionToEnum(const std::string &inUnion,
441441
} else if (inUnion == "dawn-native") {
442442
*outEnum = wgpu::FeatureName::DawnNative;
443443
} else if (inUnion == "chromium-experimental-timestamp-query-inside-passes") {
444-
*outEnum = wgpu::FeatureName::ChromiumExperimentalTimestampQueryInsidePasses;
444+
*outEnum =
445+
wgpu::FeatureName::ChromiumExperimentalTimestampQueryInsidePasses;
445446
} else if (inUnion == "implicit-device-synchronization") {
446447
*outEnum = wgpu::FeatureName::ImplicitDeviceSynchronization;
447448
} else if (inUnion == "transient-attachments") {
@@ -613,7 +614,7 @@ static void convertEnumToJSUnion(wgpu::FeatureName inEnum,
613614
case wgpu::FeatureName::ANGLETextureSharing:
614615
*outUnion = "angle-texture-sharing";
615616
break;
616-
case wgpu::FeatureName::ChromiumExperimentalSubgroupMatrix:
617+
case wgpu::FeatureName::ChromiumExperimentalSubgroupMatrix:
617618
*outUnion = "chromium-experimental-subgroups-matrix";
618619
break;
619620
case wgpu::FeatureName::PixelLocalStorageCoherent:
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { client } from "./setup";
2+
3+
describe("Error Scope", () => {
4+
it("should capture and return error messages from popErrorScope", async () => {
5+
const result = await client.eval(({ device }) => {
6+
// Invalid WGSL shader with syntax error (missing closing parenthesis)
7+
const invalidShaderWGSL = `@fragment
8+
fn main() -> @location(0) vec4f {
9+
return vec4(1.0, 0.0, 0.0, 1.0;
10+
}`;
11+
12+
device.pushErrorScope("validation");
13+
14+
// This should generate a validation error due to syntax error
15+
device.createShaderModule({
16+
code: invalidShaderWGSL,
17+
});
18+
19+
return device.popErrorScope().then((error) => {
20+
if (error) {
21+
return {
22+
hasError: true,
23+
message: error.message,
24+
messageLength: error.message.length,
25+
messageNotEmpty: error.message.length > 0,
26+
messageContainsExpected:
27+
error.message.includes("expected") ||
28+
error.message.includes("error") ||
29+
error.message.includes("parsing"),
30+
};
31+
} else {
32+
return {
33+
hasError: false,
34+
message: "",
35+
messageLength: 0,
36+
messageNotEmpty: false,
37+
messageContainsExpected: false,
38+
};
39+
}
40+
});
41+
});
42+
43+
expect(result.hasError).toBe(true);
44+
expect(result.messageNotEmpty).toBe(true);
45+
expect(result.messageLength).toBeGreaterThan(0);
46+
// The error message should contain some indication that it's a parsing error
47+
expect(result.messageContainsExpected).toBe(true);
48+
});
49+
50+
it("should return null when no error occurs", async () => {
51+
const result = await client.eval(({ device, shaders: { redFragWGSL } }) => {
52+
device.pushErrorScope("validation");
53+
54+
// This should not generate any errors
55+
device.createShaderModule({
56+
code: redFragWGSL,
57+
});
58+
59+
return device.popErrorScope().then((error) => {
60+
return {
61+
hasError: error !== null,
62+
error: error,
63+
};
64+
});
65+
});
66+
67+
expect(result.hasError).toBe(false);
68+
expect(result.error).toBe(null);
69+
});
70+
});

0 commit comments

Comments
 (0)