mirror of
https://github.com/9ParsonsB/Pulsar.git
synced 2025-07-01 16:33:43 -04:00
Expose core error logger to plugins and report custom criteria errors (#78)
* Expose core error logger to plugins and report custom criteria errors Fixes #77 This adds an error logging method on the IObservatoryCore interface that writes the exception details to ObservatoryCore's central error log (found in `${Documents}/ObservatoryErrorLog.txt`). In addition, added a timestamp to each error log. Also updates the Explorer to report Custom Criteria file load errors and execution errors to the log. Also updates HeraldNotifier to report CacheIndex.json parse failures to the error log as well. * Expand debugging/error logging in Herald; cleanup empty mp3 files Herald crashes if attempting to play 0-byte mp3s so if detected, delete, re-request (empty files can occur in some azure failure cases (ie. out of quota). Trap and log errors in other places in HeraldQueue to avoid hard crashes due to weird and wonderful unexpected stuff.
This commit is contained in:
@ -53,8 +53,9 @@ namespace Observatory.Herald
|
||||
}
|
||||
public void Load(IObservatoryCore observatoryCore)
|
||||
{
|
||||
var speechManager = new SpeechRequestManager(heraldSettings, observatoryCore.HttpClient, observatoryCore.PluginStorageFolder);
|
||||
heraldSpeech = new HeraldQueue(speechManager);
|
||||
var speechManager = new SpeechRequestManager(
|
||||
heraldSettings, observatoryCore.HttpClient, observatoryCore.PluginStorageFolder, observatoryCore.GetPluginErrorLogger(this));
|
||||
heraldSpeech = new HeraldQueue(speechManager, observatoryCore.GetPluginErrorLogger(this));
|
||||
heraldSettings.Test = TestVoice;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using NetCoreAudio;
|
||||
using System.Threading;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Observatory.Herald
|
||||
{
|
||||
@ -17,13 +19,15 @@ namespace Observatory.Herald
|
||||
private byte volume;
|
||||
private SpeechRequestManager speechManager;
|
||||
private Player audioPlayer;
|
||||
|
||||
public HeraldQueue(SpeechRequestManager speechManager)
|
||||
private Action<Exception, String> ErrorLogger;
|
||||
|
||||
public HeraldQueue(SpeechRequestManager speechManager, Action<Exception, String> errorLogger)
|
||||
{
|
||||
this.speechManager = speechManager;
|
||||
processing = false;
|
||||
notifications = new();
|
||||
audioPlayer = new();
|
||||
ErrorLogger = errorLogger;
|
||||
}
|
||||
|
||||
|
||||
@ -55,37 +59,48 @@ namespace Observatory.Herald
|
||||
|
||||
private void ProcessQueue()
|
||||
{
|
||||
|
||||
while (notifications.Any())
|
||||
|
||||
NotificationArgs notification = null;
|
||||
try
|
||||
{
|
||||
audioPlayer.SetVolume(volume).Wait();
|
||||
var notification = notifications.Dequeue();
|
||||
|
||||
Task<string>[] audioRequestTasks = new Task<string> [2];
|
||||
|
||||
|
||||
if (string.IsNullOrWhiteSpace(notification.TitleSsml))
|
||||
while (notifications.Any())
|
||||
{
|
||||
audioRequestTasks[0] = RetrieveAudioToFile(notification.Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
audioRequestTasks[0] = RetrieveAudioSsmlToFile(notification.TitleSsml);
|
||||
}
|
||||
audioPlayer.SetVolume(volume).Wait();
|
||||
notification = notifications.Dequeue();
|
||||
Debug.WriteLine("Processing notification: {0} - {1}", notification.Title, notification.Detail);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(notification.DetailSsml))
|
||||
{
|
||||
audioRequestTasks[1] = RetrieveAudioToFile(notification.Detail);
|
||||
}
|
||||
else
|
||||
{
|
||||
audioRequestTasks[1] = RetrieveAudioSsmlToFile(notification.DetailSsml);
|
||||
}
|
||||
Task<string>[] audioRequestTasks = new Task<string>[2];
|
||||
|
||||
PlayAudioRequestsSequentially(audioRequestTasks);
|
||||
if (string.IsNullOrWhiteSpace(notification.TitleSsml))
|
||||
{
|
||||
audioRequestTasks[0] = RetrieveAudioToFile(notification.Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
audioRequestTasks[0] = RetrieveAudioSsmlToFile(notification.TitleSsml);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(notification.DetailSsml))
|
||||
{
|
||||
audioRequestTasks[1] = RetrieveAudioToFile(notification.Detail);
|
||||
}
|
||||
else
|
||||
{
|
||||
audioRequestTasks[1] = RetrieveAudioSsmlToFile(notification.DetailSsml);
|
||||
}
|
||||
|
||||
PlayAudioRequestsSequentially(audioRequestTasks);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"Failed to fetch/play notification: {notification?.Title} - {notification?.Detail}");
|
||||
ErrorLogger(ex, "while retrieving and playing audio for a notification");
|
||||
}
|
||||
finally
|
||||
{
|
||||
processing = false;
|
||||
}
|
||||
|
||||
processing = false;
|
||||
}
|
||||
|
||||
private async Task<string> RetrieveAudioToFile(string text)
|
||||
@ -103,7 +118,15 @@ namespace Observatory.Herald
|
||||
foreach (var request in requestTasks)
|
||||
{
|
||||
string file = request.Result;
|
||||
audioPlayer.Play(file).Wait();
|
||||
try
|
||||
{
|
||||
Debug.WriteLine($"Playing audio file: {file}");
|
||||
audioPlayer.Play(file).Wait();
|
||||
} catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"Failed to play {file}: {ex.Message}");
|
||||
ErrorLogger(ex, $"while playing: {file}");
|
||||
}
|
||||
|
||||
while (audioPlayer.Playing)
|
||||
Thread.Sleep(50);
|
||||
|
@ -19,15 +19,18 @@ namespace Observatory.Herald
|
||||
private string ApiEndpoint;
|
||||
private DirectoryInfo cacheLocation;
|
||||
private int cacheSize;
|
||||
|
||||
internal SpeechRequestManager(HeraldSettings settings, HttpClient httpClient, string cacheFolder)
|
||||
private Action<Exception, String> ErrorLogger;
|
||||
|
||||
internal SpeechRequestManager(
|
||||
HeraldSettings settings, HttpClient httpClient, string cacheFolder, Action<Exception, String> errorLogger)
|
||||
{
|
||||
ApiKey = ObservatoryAPI.ApiKey;
|
||||
ApiEndpoint = settings.ApiEndpoint;
|
||||
this.httpClient = httpClient;
|
||||
cacheSize = Math.Max(settings.CacheSize, 1);
|
||||
cacheLocation = new DirectoryInfo(cacheFolder);
|
||||
|
||||
ErrorLogger = errorLogger;
|
||||
|
||||
if (!Directory.Exists(cacheLocation.FullName))
|
||||
{
|
||||
Directory.CreateDirectory(cacheLocation.FullName);
|
||||
@ -49,7 +52,19 @@ namespace Observatory.Herald
|
||||
|
||||
var audioFilename = cacheLocation + ssmlHash + ".mp3";
|
||||
|
||||
if (!File.Exists(audioFilename))
|
||||
FileInfo audioFileInfo = null;
|
||||
if (File.Exists(audioFilename))
|
||||
{
|
||||
audioFileInfo = new FileInfo(audioFilename);
|
||||
if (audioFileInfo.Length == 0)
|
||||
{
|
||||
File.Delete(audioFilename);
|
||||
audioFileInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (audioFileInfo == null)
|
||||
{
|
||||
using StringContent request = new(ssml)
|
||||
{
|
||||
@ -71,10 +86,10 @@ namespace Observatory.Herald
|
||||
{
|
||||
throw new PluginException("Herald", "Unable to retrieve audio data.", new Exception(response.StatusCode.ToString() + ": " + response.ReasonPhrase));
|
||||
}
|
||||
|
||||
audioFileInfo = new FileInfo(audioFilename);
|
||||
}
|
||||
|
||||
UpdateAndPruneCache(new FileInfo(audioFilename));
|
||||
UpdateAndPruneCache(audioFileInfo);
|
||||
|
||||
return audioFilename;
|
||||
}
|
||||
@ -231,6 +246,7 @@ namespace Observatory.Herald
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
cacheIndex = new();
|
||||
ErrorLogger(ex, "deserializing CacheIndex.json");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Reference in New Issue
Block a user