feat: add PostFeedback API for user feedback submission#84
Conversation
Adds support for posting non-crashing user feedback via crash type ID 36 (User.Feedback) using the existing presigned URL upload flow. The feedback zip contains feedback.json with title and description fields. - Add FeedbackPostOptions class with CrashTypeId = 36 - Add PostFeedback to CrashPostClient (creates feedback.json, delegates to PostCrashFile) - Add public PostFeedback method to BugSplat class Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ues, document surrogate pairs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a first-class “user feedback” submission API to the BugSplat .NET Standard client by introducing feedback-specific post options and wiring a new PostFeedback method through the existing presigned-URL upload flow (uploading a generated feedback.json attachment).
Changes:
- Add
FeedbackPostOptionswithCrashTypeId = 36for “User.Feedback”. - Add
BugSplat.PostFeedback(...)andCrashPostClient.PostFeedback(...)to generate/uploadfeedback.json. - Enhance
JsonSerializerto emit JSONnullfor null dictionary values and exposeEscapeJsonStringpublicly (with added tests).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| BugSplatDotNetStandard/Http/JsonObject.cs | Updates JSON serialization behavior and exposes escaping helper. |
| BugSplatDotNetStandard/BugSplatPostOptions.cs | Introduces FeedbackPostOptions with feedback crash type id. |
| BugSplatDotNetStandard/BugSplat.cs | Adds public PostFeedback entry point that delegates to CrashPostClient. |
| BugSplatDotNetStandard/Api/CrashPostClient.cs | Implements feedback upload by generating feedback.json and posting it via existing flow. |
| BugSplatDotNetStandard.Test/JsonObject.cs | Adds tests for null serialization + public escape helper + emoji escaping. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var description = overridePostOptions?.Description ?? defaultPostOptions?.Description ?? string.Empty; | ||
| var feedbackJson = $"{{\"title\":{JsonEscape(title)},\"description\":{JsonEscape(description)}}}"; | ||
| using (var feedbackTempFile = TempFileFactory.CreateFromBytes("feedback.json", Encoding.UTF8.GetBytes(feedbackJson))) | ||
| { | ||
| return await PostCrashFile( | ||
| database, | ||
| application, | ||
| version, | ||
| feedbackTempFile.File, | ||
| defaultPostOptions, | ||
| overridePostOptions | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| private static string JsonEscape(string value) | ||
| { | ||
| if (value == null) return "\"\""; | ||
| return "\"" + value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\r", "\\r").Replace("\t", "\\t") + "\""; | ||
| } |
There was a problem hiding this comment.
PostFeedback builds JSON via JsonEscape, which is a partial/duplicated JSON string escaper (doesn't handle all control characters or non-ASCII consistently, and now diverges from the existing JsonSerializer.EscapeJsonString). This can generate invalid feedback.json for some inputs. Consider removing JsonEscape and constructing feedbackJson using the existing JSON escaping/serialization utility (or a single shared helper) so escaping behavior is correct and consistent across the library.
… PostFeedback Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…h type ID, and override options Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…n permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Summary
FeedbackPostOptionsclass withCrashTypeId = 36(User.Feedback)PostFeedbackmethod toCrashPostClientthat createsfeedback.jsonwith{title, description}and delegates to existing presigned URL upload flowPostFeedback(string title, string description, FeedbackPostOptions options)toBugSplatclassTest plan
PostFeedback("Test feedback title", "Test description")with test database/app/versionfeedback.jsonis accessible in the crash details🤖 Generated with Claude Code