-
-
Notifications
You must be signed in to change notification settings - Fork 89
RG-T135 Sentry fixes #534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RG-T135 Sentry fixes #534
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,47 @@ | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using CommonServiceLocator; | ||
| using Autofac; | ||
| using Resgrid.Framework; | ||
| using Resgrid.Model; | ||
| using Resgrid.Model.Events; | ||
| using Resgrid.Model.Services; | ||
| using Resgrid.Model.Providers; | ||
|
|
||
| namespace Resgrid.Services | ||
| { | ||
| /// <summary> | ||
| /// Registered as a singleton, so the scoped department settings service is NOT resolved once and kept: from | ||
| /// the root scope it would share one unit of work, and one DB connection, with everything else resolved there, | ||
| /// and the timestamp save runs inside an audited configuration transaction. Each event instead runs in its own | ||
| /// child scope, as <see cref="ChatProvisioningEventService"/> does. | ||
| /// </summary> | ||
| public class CoreEventService : ICoreEventService | ||
| { | ||
| private readonly IEventAggregator _eventAggregator; | ||
| private readonly ILifetimeScope _lifetimeScope; | ||
|
|
||
| public CoreEventService(IEventAggregator eventAggregator) | ||
| public CoreEventService(IEventAggregator eventAggregator, ILifetimeScope lifetimeScope) | ||
| { | ||
| _eventAggregator = eventAggregator; | ||
| _lifetimeScope = lifetimeScope; | ||
|
|
||
| _eventAggregator.AddListener(departmentSettingsUpdateHandler); | ||
| // Fire-and-forget as before: the publisher (a unit, department or custom state save) is not held up. | ||
| _eventAggregator.AddListener<DepartmentSettingsUpdateEvent>(message => _ = UpdateDepartmentTimestampAsync(message)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The AddListener registration does not provide an explicit error handler, so failures from UpdateDepartmentTimestampAsync lack deterministic error handling and lifecycle cleanup. Pass HandleEventError through onError when registering the listener. Kody rule violation: Provide error handlers to subscription/listener APIs _eventAggregator.AddListener<DepartmentSettingsUpdateEvent>(message => _ = UpdateDepartmentTimestampAsync(message), onError: HandleEventError);Prompt for LLMTalk to Kody by mentioning @kody Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction. |
||
| } | ||
|
|
||
| private Action<DepartmentSettingsUpdateEvent> departmentSettingsUpdateHandler = async delegate(DepartmentSettingsUpdateEvent message) | ||
| private async Task UpdateDepartmentTimestampAsync(DepartmentSettingsUpdateEvent message) | ||
| { | ||
| var departmentSettingsService = ServiceLocator.Current.GetInstance<IDepartmentSettingsService>(); | ||
| var result = await departmentSettingsService.SaveOrUpdateSettingAsync(message.DepartmentId, DateTime.UtcNow.ToString("G"), DepartmentSettingTypes.UpdateTimestamp); | ||
| }; | ||
| try | ||
| { | ||
| using var scope = _lifetimeScope.BeginLifetimeScope(); | ||
| await scope.Resolve<IDepartmentSettingsService>().SaveOrUpdateSettingAsync(message.DepartmentId, DateTime.UtcNow.ToString("G"), DepartmentSettingTypes.UpdateTimestamp); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| // Nothing awaits this, so an escaping exception would go unobserved. | ||
| Logging.LogException(ex, $"Department update timestamp could not be saved for department {message?.DepartmentId}."); | ||
| } | ||
| } | ||
|
|
||
| public Task IncidentCommandUpdatedAsync(int departmentId, int callId) | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The external cache call can throw without recording the operation or chatChannelId, obscuring failures in ChatPermissionService and the listed callers. Wrap SetStringAsync in try/catch, log the exception with operation and channel context, and rethrow or map it to an appropriate application-level error.
Kody rule violation: Add try-catch blocks for external calls
Prompt for LLM
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.