mirror of
https://github.com/gnh1201/welsonjs.git
synced 2025-09-18 15:48:58 +00:00
updated pr-agent best practices with auto analysis
parent
16706edcd6
commit
caebf914d2
|
@ -1,3 +1,170 @@
|
|||
<!-- PR --><table><tr><td> <b><a href='https://github.com/gnh1201/welsonjs/pull/318#issuecomment-3194328108'>PR 318</a></b> (2025-08-17)
|
||||
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
|
||||
<!-- suggestion --><details><summary>[possible issue] Safely handle async init task</summary>
|
||||
|
||||
___
|
||||
|
||||
✅ Safely handle async init task
|
||||
|
||||
**The async call to fetch configuration is fire-and-forget, which can swallow exceptions and race with code that depends on _blobConfig. Capture the task and log exceptions, or await during startup. If startup cannot be async, store the task and handle its exceptions on a background continuation.**
|
||||
|
||||
[WelsonJS.Toolkit/WelsonJS.Launcher/ResourceServer.cs [45-57]](https://github.com/gnh1201/welsonjs/pull/318/files#diff-818c326b0529d19f21de13c9a00464e3eaacb0de06acbbc0bcea444e1cd3bef8R45-R57)
|
||||
|
||||
```diff
|
||||
public ResourceServer(string prefix, string resourceName, ICompatibleLogger logger = null)
|
||||
{
|
||||
_logger = logger ?? new TraceLogger();
|
||||
_prefix = prefix;
|
||||
_listener = new HttpListener();
|
||||
_resourceName = resourceName;
|
||||
|
||||
- // Fetch a blob config from Internet
|
||||
- FetchBlobConfig().ConfigureAwait(false);
|
||||
+ // Fetch a blob config from Internet (safe fire-and-forget with logging)
|
||||
+ _ = FetchBlobConfig().ContinueWith(t =>
|
||||
+ {
|
||||
+ if (t.IsFaulted)
|
||||
+ {
|
||||
+ _logger?.Error($"FetchBlobConfig failed: {t.Exception}");
|
||||
+ }
|
||||
+ }, TaskScheduler.Default);
|
||||
|
||||
// Add resource tools
|
||||
_tools.Add(new ResourceTools.Completion(this, _httpClient));
|
||||
_tools.Add(new ResourceTools.Settings(this, _httpClient));
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Suggestion importance[1-10]: 6
|
||||
|
||||
__
|
||||
|
||||
Why: The suggestion correctly identifies a "fire-and-forget" async call in a constructor, which can lead to race conditions for code depending on `_blobConfig`, a valid and important architectural concern.
|
||||
|
||||
___
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
<!-- suggestion --><details><summary>[general] Make trace listener setup safer</summary>
|
||||
|
||||
___
|
||||
|
||||
✅ Make trace listener setup safer
|
||||
|
||||
**Adding a listener in a static constructor risks duplicate listeners if multiple AppDomains or re-initializations occur and can throw if file is locked. Guard against duplicates and wrap setup in try/catch to avoid crashing logging initialization.**
|
||||
|
||||
[WelsonJS.Toolkit/WelsonJS.Launcher/TraceLogger.cs [17-24]](https://github.com/gnh1201/welsonjs/pull/318/files#diff-1c64dc458a9c5d10aefc6236be3d746a16d152b194a86cff3aead853a35b395eR17-R24)
|
||||
|
||||
```diff
|
||||
static TraceLogger()
|
||||
{
|
||||
- _logFileName = typeof(TraceLogger).Namespace + ".log";
|
||||
-
|
||||
- var textWriterTraceListener = new TextWriterTraceListener(_logFileName);
|
||||
- Trace.Listeners.Add(textWriterTraceListener);
|
||||
- Trace.AutoFlush = true;
|
||||
+ try
|
||||
+ {
|
||||
+ _logFileName = (typeof(TraceLogger).Namespace ?? "WelsonJS") + ".log";
|
||||
+ // Avoid adding duplicate listeners for the same file
|
||||
+ foreach (TraceListener l in Trace.Listeners)
|
||||
+ {
|
||||
+ if (l is TextWriterTraceListener tw && string.Equals(tw.Writer?.ToString(), _logFileName))
|
||||
+ {
|
||||
+ Trace.AutoFlush = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ var textWriterTraceListener = new TextWriterTraceListener(_logFileName);
|
||||
+ Trace.Listeners.Add(textWriterTraceListener);
|
||||
+ Trace.AutoFlush = true;
|
||||
+ }
|
||||
+ catch
|
||||
+ {
|
||||
+ // Swallow to avoid failing app startup due to logging issues
|
||||
+ }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Suggestion importance[1-10]: 7
|
||||
|
||||
__
|
||||
|
||||
Why: The suggestion correctly identifies that adding a trace listener in a static constructor can lead to duplicates and proposes a valid improvement to prevent this, enhancing the robustness of the logging initialization.
|
||||
|
||||
___
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
<!-- suggestion --><details><summary>[learned best practice] Guard deserialization with null checks</summary>
|
||||
|
||||
___
|
||||
|
||||
✅ Guard deserialization with null checks
|
||||
|
||||
**Add a null check on the deserialization result before using it to avoid possible NullReferenceException. Also validate that the stream is not null before constructing the reader.**
|
||||
|
||||
[WelsonJS.Toolkit/WelsonJS.Launcher/ResourceServer.cs [448-453]](https://github.com/gnh1201/welsonjs/pull/318/files#diff-818c326b0529d19f21de13c9a00464e3eaacb0de06acbbc0bcea444e1cd3bef8R448-R453)
|
||||
|
||||
```diff
|
||||
using (var response = await _httpClient.GetStreamAsync(url))
|
||||
-using (var reader = new StreamReader(response))
|
||||
{
|
||||
- var serializer = new XmlSerializer(typeof(BlobConfig));
|
||||
- _blobConfig = (BlobConfig)serializer.Deserialize(reader);
|
||||
+ if (response == null)
|
||||
+ {
|
||||
+ _logger?.Warn("Blob config response stream was null.");
|
||||
+ return;
|
||||
+ }
|
||||
+ using (var reader = new StreamReader(response))
|
||||
+ {
|
||||
+ var serializer = new XmlSerializer(typeof(BlobConfig));
|
||||
+ var deserialized = serializer.Deserialize(reader) as BlobConfig;
|
||||
+ if (deserialized == null)
|
||||
+ {
|
||||
+ _logger?.Warn("Failed to deserialize BlobConfig (null result).");
|
||||
+ return;
|
||||
+ }
|
||||
+ _blobConfig = deserialized;
|
||||
+ }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Suggestion importance[1-10]: 6
|
||||
|
||||
__
|
||||
|
||||
Why:
|
||||
Relevant best practice - Add null/undefined checks before accessing object properties or calling methods to prevent runtime exceptions.
|
||||
|
||||
___
|
||||
|
||||
</details>
|
||||
|
||||
___
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='https://github.com/gnh1201/welsonjs/pull/309#issuecomment-3172799544'>PR 309</a></b> (2025-08-10)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -40,6 +207,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='https://github.com/gnh1201/welsonjs/pull/307#issuecomment-3154116053'>PR 307</a></b> (2025-08-05)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -131,6 +300,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='3055522397'>PR 284</a></b> (2025-07-10)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -201,6 +372,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='3006712754'>PR 279</a></b> (2025-06-26)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -253,6 +426,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='2982794401'>PR 276</a></b> (2025-06-18)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -302,6 +477,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='2953770469'>PR 272</a></b> (2025-06-08)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -361,6 +538,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='2868572186'>PR 249</a></b> (2025-05-10)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -431,6 +610,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='2868568893'>PR 248</a></b> (2025-05-10)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -558,6 +739,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='2850302530'>PR 245</a></b> (2025-05-05)
|
||||
|
||||
</td></tr></table>
|
||||
|
@ -653,6 +836,8 @@ ___
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- PR --><table><tr><td> <b><a href='2832883684'>PR 242</a></b> (2025-04-27)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user