feat: exceptions
Some checks failed
build-packages / meilisearch-dotnet-packages (push) Has been cancelled
Some checks failed
build-packages / meilisearch-dotnet-packages (push) Has been cancelled
This commit is contained in:
parent
ab8c4398f8
commit
430e1d8617
@ -1,12 +0,0 @@
|
||||
namespace meilisearch.NET.Exceptions;
|
||||
|
||||
public class DocumentBatchException : DocumentManagementException
|
||||
{
|
||||
public int BatchSize { get; }
|
||||
|
||||
public DocumentBatchException(int batchSize, Exception innerException)
|
||||
: base($"Failed to process batch of {batchSize} documents", innerException)
|
||||
{
|
||||
BatchSize = batchSize;
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
namespace meilisearch.NET.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Exception thrown when there are issues with document management
|
||||
/// </summary>
|
||||
public class DocumentManagementException : MeiliSearchException
|
||||
{
|
||||
public DocumentManagementException(string message) : base(message) { }
|
||||
public DocumentManagementException(string message, Exception innerException) : base(message, innerException) { }
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace meilisearch.NET.Exceptions;
|
||||
|
||||
public class DocumentSyncException : DocumentManagementException
|
||||
{
|
||||
public DocumentSyncException(string message, Exception innerException)
|
||||
: base($"Failed to sync documents: {message}", innerException) { }
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace meilisearch.NET.Exceptions;
|
||||
|
||||
public class DocumentValidationException : DocumentManagementException
|
||||
{
|
||||
public DocumentValidationException(string message)
|
||||
: base($"Document validation failed: {message}") { }
|
||||
}
|
12
meilisearch.NET/Exceptions/IndexAlreadyExistsException.cs
Normal file
12
meilisearch.NET/Exceptions/IndexAlreadyExistsException.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace meilisearch.NET.Exceptions;
|
||||
|
||||
public class IndexAlreadyExistsException : IndexManagementException
|
||||
{
|
||||
public string IndexName { get; }
|
||||
|
||||
public IndexAlreadyExistsException(string indexName)
|
||||
: base($"Index '{indexName}' already exists")
|
||||
{
|
||||
IndexName = indexName;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
namespace meilisearch.NET.Exceptions;
|
||||
|
||||
public class IndexLimitExceededException : IndexManagementException
|
||||
public class IndexLimitReachedException : IndexManagementException
|
||||
{
|
||||
public IndexLimitExceededException()
|
||||
public IndexLimitReachedException()
|
||||
: base("Maximum number of indexes (1000) has been reached") { }
|
||||
}
|
@ -2,5 +2,5 @@
|
||||
|
||||
public class ProcessStartException : ProcessManagementException
|
||||
{
|
||||
public ProcessStartException(string message) : base($"Failed to start Meilisearch process: {message}") { }
|
||||
public ProcessStartException(Exception innerException, string message) : base($"Failed to start Meilisearch process: {message}", innerException) { }
|
||||
}
|
@ -2,5 +2,5 @@
|
||||
|
||||
public class ProcessStopException : ProcessManagementException
|
||||
{
|
||||
public ProcessStopException(string message) : base($"Failed to stop Meilisearch process: {message}") { }
|
||||
public ProcessStopException(Exception innerException, string message) : base($"Failed to stop Meilisearch process: {message}", innerException) { }
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using Meilisearch;
|
||||
using meilisearch.NET.Exceptions;
|
||||
using meilisearch.NET.Interfaces;
|
||||
using meilisearch.NET.Services.ProcessManagement;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace meilisearch.NET.Services.DocumentManagement;
|
||||
@ -9,13 +11,15 @@ namespace meilisearch.NET.Services.DocumentManagement;
|
||||
public class DocumentManager:IDocumentManager
|
||||
{
|
||||
private readonly ILogger<DocumentManager> _logger;
|
||||
private readonly MeiliSearchProcessManager _meiliSearchProcessManager;
|
||||
private readonly MeilisearchClient _client;
|
||||
|
||||
private const int THRESHOLD = 100;
|
||||
private ObservableCollection<KeyValuePair<string,IDocument>> _documentCollection;
|
||||
|
||||
public DocumentManager(MeilisearchClient client, ILogger<DocumentManager> logger)
|
||||
public DocumentManager(MeilisearchClient client, ILogger<DocumentManager> logger, MeiliSearchProcessManager meiliSearchProcessManager)
|
||||
{
|
||||
_meiliSearchProcessManager = meiliSearchProcessManager;
|
||||
_logger = logger;
|
||||
_client = client;
|
||||
_documentCollection = new ObservableCollection<KeyValuePair<string,IDocument>>();
|
||||
@ -24,6 +28,9 @@ public class DocumentManager:IDocumentManager
|
||||
|
||||
public async Task AddDocumentAsync(string repositoryId, IDocument document, bool autoCommit = false)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
_logger.LogTrace($"Adding document '{document.Id}' to repository '{repositoryId}'...");
|
||||
_documentCollection.Add(new KeyValuePair<string, IDocument>(repositoryId, document));
|
||||
_logger.LogInformation($"Document {document.Id} added to collection.");
|
||||
@ -34,6 +41,9 @@ public class DocumentManager:IDocumentManager
|
||||
}
|
||||
public void AddDocument(string repositoryId, IDocument document, bool autoCommit = false)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
_logger.LogTrace($"Adding document '{document.Id}' to repository '{repositoryId}'...");
|
||||
_documentCollection.Add(new KeyValuePair<string, IDocument>(repositoryId, document));
|
||||
_logger.LogInformation($"Document {document.Id} added to collection.");
|
||||
@ -44,6 +54,9 @@ public class DocumentManager:IDocumentManager
|
||||
}
|
||||
public void SyncDocumentsToServer()
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var grouped = _documentCollection.GroupBy(pair => pair.Key)
|
||||
.ToDictionary(group => group.Key, group => group.Select(pair => pair.Value).ToList());
|
||||
foreach (var repository in grouped)
|
||||
@ -53,9 +66,12 @@ public class DocumentManager:IDocumentManager
|
||||
_documentCollection.Clear();
|
||||
var result = RetryAsync(() => repositoryIndex.AddDocumentsAsync(repository.Value, "id")).Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
public async Task SyncDocumentsToServerAsync()
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var grouped = _documentCollection.GroupBy(pair => pair.Key)
|
||||
.ToDictionary(group => group.Key, group => group.Select(pair => pair.Value).ToList());
|
||||
foreach (var repository in grouped)
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using Meilisearch;
|
||||
using meilisearch.NET.Exceptions;
|
||||
using meilisearch.NET.Interfaces;
|
||||
using meilisearch.NET.Services.ProcessManagement;
|
||||
using Meilisearch.QueryParameters;
|
||||
@ -16,35 +17,36 @@ public class IndexManager:IIndexManager
|
||||
private readonly string _indexBasePath = Path.Combine(AppContext.BaseDirectory, "db", "indexes" );
|
||||
private readonly ILogger<IndexManager> _logger;
|
||||
private readonly MeilisearchClient _client;
|
||||
private readonly MeiliSearchProcessManager _processManager;
|
||||
private readonly MeiliSearchProcessManager _meiliSearchProcessManager;
|
||||
|
||||
public IndexManager(ILogger<IndexManager> logger, MeilisearchClient client, MeiliSearchProcessManager processManager)
|
||||
public IndexManager(ILogger<IndexManager> logger, MeilisearchClient client, MeiliSearchProcessManager meiliSearchProcessManager)
|
||||
{
|
||||
_processManager = processManager;
|
||||
_meiliSearchProcessManager = meiliSearchProcessManager;
|
||||
_client = client;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
public Task<List<string>> GetAllIndexes()
|
||||
public async Task<List<string>> GetAllIndexes()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
_logger.LogTrace("Fetching all indexes from Meilisearch server created with the SDK...");
|
||||
var result = _client.GetAllIndexesAsync().Result.Results.Select(x => x.Uid).Where(x=>x!="index_bindings").ToList();
|
||||
_logger.LogInformation($"Fetched {result.Count} indexes from Meilisearch server.");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void CreateIndex<T>(string indexName) where T : IDocument
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var indexes = GetAllIndexes().Result;
|
||||
if(indexes.Count>=1000)
|
||||
{
|
||||
_logger.LogWarning("Maximum number of indexes reached, cannot create new index.");
|
||||
return;
|
||||
}
|
||||
throw new IndexLimitReachedException();
|
||||
|
||||
if (indexes.Any(x => x == indexName))
|
||||
{
|
||||
_logger.LogWarning($"Index {indexName} already exists, skipping creation of index.");
|
||||
return;
|
||||
}
|
||||
throw new IndexAlreadyExistsException(indexName);
|
||||
|
||||
var foldersBefore = Directory.GetDirectories(_indexBasePath);
|
||||
_logger.LogTrace($"Creating index '{indexName}'...");
|
||||
@ -74,18 +76,16 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
public async Task CreateIndexAsync<T>(string indexName) where T : IDocument
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var indexes = await GetAllIndexes();
|
||||
|
||||
if(indexes.Count>=1000)
|
||||
{
|
||||
_logger.LogWarning("Maximum number of indexes reached, cannot create new index.");
|
||||
return;
|
||||
}
|
||||
throw new IndexLimitReachedException();
|
||||
|
||||
if (indexes.Any(x => x == indexName))
|
||||
{
|
||||
_logger.LogWarning($"Index {indexName} already exists, skipping creation of index.");
|
||||
return;
|
||||
}
|
||||
throw new IndexAlreadyExistsException(indexName);
|
||||
|
||||
var foldersBefore = Directory.GetDirectories(_indexBasePath);
|
||||
_logger.LogTrace($"Creating index '{indexName}'...");
|
||||
@ -114,11 +114,13 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
public void DeleteIndex(string indexName)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var indexes = _client.GetAllIndexesAsync().Result;
|
||||
if (indexes.Results.Any(x => x.Uid == indexName)==false)
|
||||
{
|
||||
_logger.LogWarning($"Index '{indexName}' does not exist, skipping deletion of index.");
|
||||
return;
|
||||
throw new IndexNotFoundException(indexName);
|
||||
}
|
||||
_logger.LogTrace($"Deleting index '{indexName}'...");
|
||||
_client.DeleteIndexAsync(indexName).Wait();
|
||||
@ -127,11 +129,13 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
public async Task DeleteIndexAsync(string indexName)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var indexes = _client.GetAllIndexesAsync().Result;
|
||||
if (indexes.Results.Any(x => x.Uid == indexName)==false)
|
||||
{
|
||||
_logger.LogWarning($"Index '{indexName}' does not exist, skipping deletion of index.");
|
||||
return;
|
||||
throw new IndexNotFoundException(indexName);
|
||||
}
|
||||
_logger.LogTrace($"Deleting index '{indexName}'...");
|
||||
await _client.DeleteIndexAsync(indexName);
|
||||
@ -140,6 +144,9 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
public void SetIndexEnabled(string indexName, bool enabled)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
_logger.LogTrace($"Updating index '{indexName}' status to {enabled}...");
|
||||
if(enabled)
|
||||
{
|
||||
@ -153,6 +160,9 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
public async Task SetIndexEnabledAsync(string indexName, bool enabled)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
_logger.LogTrace($"Updating index '{indexName}' status to {enabled}...");
|
||||
if(enabled)
|
||||
{
|
||||
@ -166,6 +176,9 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
public long GetIndexStorageUsage(string indexName, bool useCompressedSize = true)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var doc = _client.GetIndexAsync("index_bindings").Result.GetDocumentAsync<Models.Index>(indexName).Result;
|
||||
|
||||
if (doc.IsCompressed)
|
||||
@ -176,21 +189,22 @@ public class IndexManager:IIndexManager
|
||||
var indexPath = GetIndexFilePath(indexName).Result+".zip";
|
||||
if (!File.Exists(indexPath))
|
||||
{
|
||||
_logger.LogWarning($"Compressed index not found at: {indexPath}");
|
||||
return 0;
|
||||
throw new FileNotFoundException($"Compressed index not found at: {indexPath}");
|
||||
}
|
||||
return new FileInfo(indexPath).Length;
|
||||
}
|
||||
var path = Path.Combine(_indexBasePath, doc.FolderId);
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
_logger.LogWarning($"Index directory not found at: {path}");
|
||||
return 0;
|
||||
throw new DirectoryNotFoundException($"Index directory not found at: {path}");
|
||||
}
|
||||
return new DirectoryInfo(path).GetFiles().Sum(f => f.Length);
|
||||
}
|
||||
public long GetTotalStorageUsage(bool useCompressedSize = true)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var result = _client.GetIndexAsync("index_bindings").Result.GetDocumentsAsync<Models.Index>(new DocumentsQuery(){Limit = 1000}).Result;
|
||||
var total = 0L;
|
||||
foreach (var index in result.Results)
|
||||
@ -208,6 +222,9 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
public async Task<long> GetIndexStorageUsageAsync(string indexName, bool useCompressedSize = true)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var doc = _client.GetIndexAsync("index_bindings").Result.GetDocumentAsync<Models.Index>(indexName).Result;
|
||||
|
||||
if (doc.IsCompressed)
|
||||
@ -218,21 +235,22 @@ public class IndexManager:IIndexManager
|
||||
var indexPath = await GetIndexFilePath(indexName)+".zip";
|
||||
if (!File.Exists(indexPath))
|
||||
{
|
||||
_logger.LogWarning($"Compressed index not found at: {indexPath}");
|
||||
return 0;
|
||||
throw new FileNotFoundException($"Compressed index not found at: {indexPath}");
|
||||
}
|
||||
return new FileInfo(indexPath).Length;
|
||||
}
|
||||
var path = Path.Combine(_indexBasePath, doc.FolderId);
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
_logger.LogWarning($"Index directory not found at: {path}");
|
||||
return 0;
|
||||
throw new DirectoryNotFoundException($"Index directory not found at: {path}");
|
||||
}
|
||||
return new DirectoryInfo(path).GetFiles().Sum(f => f.Length);
|
||||
}
|
||||
public async Task<long> GetTotalStorageUsageAsync(bool useCompressedSize = true)
|
||||
{
|
||||
if (!_meiliSearchProcessManager.IsProcessRunning())
|
||||
throw new ProcessNotRunningException();
|
||||
|
||||
var result = _client.GetIndexAsync("index_bindings").Result.GetDocumentsAsync<Models.Index>(new DocumentsQuery(){Limit = 1000}).Result;
|
||||
var total = 0L;
|
||||
foreach (var index in result.Results)
|
||||
@ -278,8 +296,7 @@ public class IndexManager:IIndexManager
|
||||
var indexPath = await GetIndexFilePath(indexName);
|
||||
if (!Directory.Exists(indexPath))
|
||||
{
|
||||
_logger.LogWarning($"Index directory not found at: {indexPath}");
|
||||
return;
|
||||
throw new DirectoryNotFoundException($"Index directory not found at: {indexPath}");
|
||||
}
|
||||
|
||||
var compressedPath = indexPath + ".zip";
|
||||
@ -322,10 +339,9 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError($"Failed to compress index '{indexName}': {ex.Message}");
|
||||
throw;
|
||||
throw new IndexCompressionException(indexName, "compress", ex);
|
||||
}
|
||||
_processManager.StopProcess();
|
||||
_meiliSearchProcessManager.StopProcess();
|
||||
}
|
||||
|
||||
private async Task DecompressIndex(string indexName)
|
||||
@ -336,8 +352,7 @@ public class IndexManager:IIndexManager
|
||||
|
||||
if (!File.Exists(compressedPath))
|
||||
{
|
||||
_logger.LogWarning($"Compressed index not found at: {compressedPath}");
|
||||
return;
|
||||
throw new FileNotFoundException($"Compressed index not found at: {compressedPath}");
|
||||
}
|
||||
|
||||
_logger.LogTrace($"Decompressing index '{indexName}' to {extractPath}...");
|
||||
@ -379,8 +394,7 @@ public class IndexManager:IIndexManager
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError($"Failed to decompress index '{indexName}': {ex.Message}");
|
||||
throw;
|
||||
throw new IndexCompressionException(indexName, "decompress", ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using meilisearch.NET.Exceptions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace meilisearch.NET.Services.ProcessManagement;
|
||||
@ -35,14 +36,20 @@ public abstract class BaseProcessManager : IProcessManager
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"Failed to start {GetProcessName()}: {ex.Message}");
|
||||
throw;
|
||||
throw new ProcessStartException(ex,ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StopProcess()
|
||||
{
|
||||
Process?.Kill();
|
||||
try
|
||||
{
|
||||
Process?.Kill();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError($"Error stopping {GetProcessName()} process: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsProcessRunning()
|
||||
|
Loading…
x
Reference in New Issue
Block a user