Skip to content

Commit 8b47f06

Browse files
author
Vadim Belov
committed
2 parents 4b541b2 + e5c081e commit 8b47f06

27 files changed

Lines changed: 310 additions & 271 deletions

File tree

Sources/EasyExtensions.EntityFrameworkCore/Exceptions/AccessException.cs renamed to Sources/EasyExtensions.AspNetCore/Exceptions/AccessException.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33

44
using System.Net;
55

6-
namespace EasyExtensions.EntityFrameworkCore.Exceptions
6+
namespace EasyExtensions.AspNetCore.Exceptions
77
{
88
/// <summary>
99
/// Access exception.
1010
/// </summary>
1111
/// <param name="objectName"> Object name. </param>
12-
[Serializable]
1312
public class AccessException(string objectName)
1413
: WebApiException(HttpStatusCode.Forbidden, objectName, "Access denied")
1514
{ }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2025–2026 Vadim Belov <https://belov.us>
3+
4+
using System.Net;
5+
6+
namespace EasyExtensions.AspNetCore.Exceptions
7+
{
8+
/// <summary>
9+
/// Represents an exception that is thrown when a request is unauthorized or invalid for a specified object.
10+
/// </summary>
11+
/// <param name="objectName">The name of the object associated with the unauthorized or invalid request.</param>
12+
public class BadRequestException(string objectName)
13+
: WebApiException(HttpStatusCode.BadRequest, objectName, "Bad request")
14+
{ }
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2025–2026 Vadim Belov <https://belov.us>
3+
4+
using System.Net;
5+
6+
namespace EasyExtensions.AspNetCore.Exceptions
7+
{
8+
/// <summary>
9+
/// Represents an exception that is thrown when an attempt is made to create or add an object that already exists.
10+
/// </summary>
11+
/// <remarks>This exception corresponds to an HTTP 409 Conflict response and is typically used in web APIs
12+
/// to indicate that a resource with the specified name already exists. Use this exception to signal duplicate
13+
/// creation attempts in resource management scenarios.</remarks>
14+
/// <param name="objectName">The name of the object that caused the conflict.</param>
15+
public class DuplicateException(string objectName)
16+
: WebApiException(HttpStatusCode.Conflict, objectName, "Object already exists")
17+
{ }
18+
}

Sources/EasyExtensions.EntityFrameworkCore/Exceptions/EntityInvalidTypeException.cs renamed to Sources/EasyExtensions.AspNetCore/Exceptions/EntityInvalidTypeException.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
// SPDX-License-Identifier: MIT
22
// Copyright (c) 2025–2026 Vadim Belov <https://belov.us>
33

4-
namespace EasyExtensions.EntityFrameworkCore.Exceptions
4+
using System;
5+
6+
namespace EasyExtensions.AspNetCore.Exceptions
57
{
68
/// <summary>
7-
/// The exception that is thrown when an entity type is invalid.
9+
/// Represents an exception that is thrown when an entity is of an invalid type.
810
/// </summary>
11+
/// <param name="message">The message that describes the error.</param>
912
public class EntityInvalidTypeException(string message) : Exception(message)
1013
{
1114
/// <summary>

Sources/EasyExtensions.EntityFrameworkCore/Exceptions/EntityNotFoundException.cs renamed to Sources/EasyExtensions.AspNetCore/Exceptions/EntityNotFoundException.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
using System.Net;
55

6-
namespace EasyExtensions.EntityFrameworkCore.Exceptions
6+
namespace EasyExtensions.AspNetCore.Exceptions
77
{
88
/// <summary>
9-
/// Entity not found exception.
9+
/// Represents an exception that is thrown when a requested entity cannot be found.
1010
/// </summary>
11-
/// <param name="objectName"> Object name. </param>
12-
[Serializable]
11+
/// <param name="objectName">The name of the entity that was not found. This value is included in the exception details to identify the
12+
/// missing entity.</param>
1313
public class EntityNotFoundException(string objectName)
1414
: WebApiException(HttpStatusCode.NotFound, objectName, "Entity was not found")
1515
{ }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2025–2026 Vadim Belov <https://belov.us>
3+
4+
using System.Net;
5+
6+
namespace EasyExtensions.AspNetCore.Exceptions
7+
{
8+
/// <summary>
9+
/// Represents an exception that is thrown when an operation is attempted without proper authorization.
10+
/// </summary>
11+
/// <remarks>This exception corresponds to an HTTP 401 Unauthorized response. It is typically used in web
12+
/// API scenarios to indicate that the caller must authenticate or does not have permission to access the specified
13+
/// resource.</remarks>
14+
/// <param name="objectName">The name of the object or resource for which access was denied.</param>
15+
public class UnauthorizedException(string objectName)
16+
: WebApiException(HttpStatusCode.Unauthorized, objectName, "Unathorized")
17+
{ }
18+
}

Sources/EasyExtensions.EntityFrameworkCore/Exceptions/WebApiException.cs renamed to Sources/EasyExtensions.AspNetCore/Exceptions/WebApiException.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,24 @@
33

44
using EasyExtensions.Abstractions;
55
using EasyExtensions.Models;
6+
using System;
7+
using System.Collections.Generic;
68
using System.Diagnostics;
79
using System.Net;
810

9-
namespace EasyExtensions.EntityFrameworkCore.Exceptions
11+
namespace EasyExtensions.AspNetCore.Exceptions
1012
{
1113
/// <summary>
12-
/// Base web api exception.
14+
/// Represents an exception that is thrown to indicate an error response from a Web API, including an associated
15+
/// HTTP status code and object name.
1316
/// </summary>
14-
/// <param name="statusCode"> HTTP status code. </param>
15-
/// <param name="objectName"> Object name. </param>
16-
/// <param name="message"> Exception message. </param>
17+
/// <remarks>Use this exception to return detailed error information from Web API actions, including a
18+
/// status code and object-specific error details. The exception can be used to generate standardized error
19+
/// responses for clients.</remarks>
20+
/// <param name="statusCode">The HTTP status code to associate with the exception. Indicates the nature of the error as defined by the HTTP
21+
/// protocol.</param>
22+
/// <param name="objectName">The name of the object or entity related to the error. Used to identify the source of the error in the response.</param>
23+
/// <param name="message">The error message that describes the reason for the exception.</param>
1724
public class WebApiException(HttpStatusCode statusCode, string objectName, string message) : Exception(message), IHttpError
1825
{
1926
/// <summary>

Sources/EasyExtensions.Crypto.Tests.Charts/advanced_analysis.py

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,8 @@
1-
import re
21
import matplotlib.pyplot as plt
32
import pandas as pd
43
import numpy as np
54
import seaborn as sns
6-
7-
8-
def parse_test_results(filename):
9-
"""Parse performance test results from a file"""
10-
11-
with open(filename, 'r', encoding='utf-8') as f:
12-
content = f.read()
13-
14-
# Find result sections
15-
encrypt_section = re.search(
16-
r'=== ENCRYPTION THREAD/CHUNK SWEEP ===(.*?)(?===|$)', content, re.DOTALL)
17-
decrypt_section = re.search(
18-
r'=== DECRYPTION THREAD/CHUNK SWEEP ===(.*?)(?===|$)', content, re.DOTALL)
19-
20-
def extract_data(section_text):
21-
"""Extract data from a text section"""
22-
if not section_text:
23-
return pd.DataFrame()
24-
25-
# Ищем строки с данными (формат: число | число | число.число)
26-
pattern = r'(\d+)\s*\|\s*(\d+)\s*\|\s*([\d.]+)'
27-
matches = re.findall(pattern, section_text)
28-
29-
data = []
30-
for match in matches:
31-
threads = int(match[0])
32-
chunk_mb = int(match[1])
33-
throughput = float(match[2])
34-
data.append({'Threads': threads, 'ChunkMB': chunk_mb,
35-
'Throughput': throughput})
36-
37-
return pd.DataFrame(data)
38-
39-
encrypt_data = extract_data(
40-
encrypt_section.group(1) if encrypt_section else "")
41-
decrypt_data = extract_data(
42-
decrypt_section.group(1) if decrypt_section else "")
43-
44-
return encrypt_data, decrypt_data
5+
from test_parser import parse_test_results
456

467

478
def create_advanced_plots(encrypt_data, decrypt_data):

Sources/EasyExtensions.Crypto.Tests.Charts/mega_advanced_analysis.py

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,10 @@
1-
import re
21
import matplotlib.pyplot as plt
32
import pandas as pd
43
import numpy as np
54
import seaborn as sns
65
from matplotlib.patches import Rectangle
76
import matplotlib.gridspec as gridspec
8-
9-
10-
def parse_test_results(filename):
11-
"""Parse performance test results from a file"""
12-
13-
with open(filename, 'r', encoding='utf-8') as f:
14-
content = f.read()
15-
16-
# Find result sections
17-
encrypt_section = re.search(
18-
r'=== ENCRYPTION THREAD/CHUNK SWEEP ===(.*?)(?===|$)', content, re.DOTALL)
19-
decrypt_section = re.search(
20-
r'=== DECRYPTION THREAD/CHUNK SWEEP ===(.*?)(?===|$)', content, re.DOTALL)
21-
22-
def extract_data(section_text):
23-
"""Extract data from a text section"""
24-
if not section_text:
25-
return pd.DataFrame()
26-
27-
# Ищем строки с данными (формат: число | число | число.число)
28-
pattern = r'(\d+)\s*\|\s*(\d+)\s*\|\s*([\d.]+)'
29-
matches = re.findall(pattern, section_text)
30-
31-
data = []
32-
for match in matches:
33-
threads = int(match[0])
34-
chunk_mb = int(match[1])
35-
throughput = float(match[2])
36-
data.append({'Threads': threads, 'ChunkMB': chunk_mb,
37-
'Throughput': throughput})
38-
39-
return pd.DataFrame(data)
40-
41-
encrypt_data = extract_data(
42-
encrypt_section.group(1) if encrypt_section else "")
43-
decrypt_data = extract_data(
44-
decrypt_section.group(1) if decrypt_section else "")
45-
46-
return encrypt_data, decrypt_data
7+
from test_parser import parse_test_results
478

489

4910
def create_mega_analysis(encrypt_data, decrypt_data):

Sources/EasyExtensions.Crypto.Tests.Charts/simple_charts.py

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,7 @@
1-
import re
21
import matplotlib.pyplot as plt
32
import pandas as pd
43
import numpy as np
5-
6-
7-
def parse_test_results(filename):
8-
"""Parse performance test results from a file"""
9-
10-
with open(filename, 'r', encoding='utf-8') as f:
11-
content = f.read()
12-
13-
# Find result sections
14-
encrypt_section = re.search(
15-
r'=== ENCRYPTION THREAD/CHUNK SWEEP ===(.*?)(?===|$)', content, re.DOTALL)
16-
decrypt_section = re.search(
17-
r'=== DECRYPTION THREAD/CHUNK SWEEP ===(.*?)(?===|$)', content, re.DOTALL)
18-
19-
def extract_data(section_text):
20-
"""Extract data from a text section"""
21-
if not section_text:
22-
return pd.DataFrame()
23-
24-
# Find data lines (format: number | number | number.number)
25-
pattern = r'(\d+)\s*\|\s*(\d+)\s*\|\s*([\d.]+)'
26-
matches = re.findall(pattern, section_text)
27-
28-
data = []
29-
for match in matches:
30-
threads = int(match[0])
31-
chunk_mb = int(match[1])
32-
throughput = float(match[2])
33-
data.append({'Threads': threads, 'ChunkMB': chunk_mb,
34-
'Throughput': throughput})
35-
36-
return pd.DataFrame(data)
37-
38-
encrypt_data = extract_data(
39-
encrypt_section.group(1) if encrypt_section else "")
40-
decrypt_data = extract_data(
41-
decrypt_section.group(1) if decrypt_section else "")
42-
43-
return encrypt_data, decrypt_data
4+
from test_parser import parse_test_results
445

456

467
def create_plots(encrypt_data, decrypt_data):

0 commit comments

Comments
 (0)