Skip to content

Commit 9203cd5

Browse files
authored
Merge pull request #45 from PandaTechAM/development
updated missing feature
2 parents 9ac34fd + 7c0e234 commit 9203cd5

File tree

9 files changed

+241
-39
lines changed

9 files changed

+241
-39
lines changed

.editorconfig

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
###############################
2+
# PandaTech Editor Config #
3+
###############################
4+
5+
6+
################################
7+
# ReSharper Generated Settings #
8+
################################
9+
10+
[*]
11+
charset = utf-8-bom
12+
end_of_line = crlf
13+
trim_trailing_whitespace = false
14+
insert_final_newline = false
15+
indent_style = space
16+
indent_size = 4
17+
18+
# Microsoft .NET properties
19+
csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:suggestion
20+
csharp_style_prefer_utf8_string_literals = true:suggestion
21+
csharp_style_var_elsewhere = true:suggestion
22+
csharp_style_var_for_built_in_types = true:suggestion
23+
csharp_style_var_when_type_is_apparent = true:suggestion
24+
dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
25+
dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
26+
dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
27+
dotnet_naming_rule.unity_serialized_field_rule.severity = warning
28+
dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
29+
dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
30+
dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
31+
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
32+
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
33+
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
34+
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
35+
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
36+
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
37+
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
38+
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
39+
dotnet_style_predefined_type_for_member_access = true:suggestion
40+
dotnet_style_qualification_for_event = false:suggestion
41+
dotnet_style_qualification_for_field = false:suggestion
42+
dotnet_style_qualification_for_method = false:suggestion
43+
dotnet_style_qualification_for_property = false:suggestion
44+
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
45+
46+
# ReSharper properties
47+
resharper_align_linq_query = true
48+
resharper_align_multiline_calls_chain = true
49+
resharper_apply_auto_detected_rules = false
50+
resharper_braces_for_for = required
51+
resharper_braces_for_foreach = required
52+
resharper_braces_for_ifelse = required
53+
resharper_braces_for_while = required
54+
resharper_cpp_insert_final_newline = true
55+
resharper_csharp_indent_size = 3
56+
resharper_csharp_max_enum_members_on_line = 0
57+
resharper_csharp_tab_width = 3
58+
resharper_csharp_wrap_arguments_style = chop_if_long
59+
resharper_csharp_wrap_parameters_style = chop_if_long
60+
resharper_formatter_off_tag = @formatter:off
61+
resharper_formatter_on_tag = @formatter:on
62+
resharper_formatter_tags_enabled = true
63+
resharper_keep_existing_declaration_parens_arrangement = false
64+
resharper_keep_existing_expr_member_arrangement = false
65+
resharper_keep_existing_initializer_arrangement = false
66+
resharper_keep_existing_switch_expression_arrangement = false
67+
resharper_max_array_initializer_elements_on_line = 0
68+
resharper_max_initializer_elements_on_line = 0
69+
resharper_place_accessorholder_attribute_on_same_line = false
70+
resharper_place_accessor_attribute_on_same_line = false
71+
resharper_place_field_attribute_on_same_line = false
72+
resharper_place_simple_anonymousmethod_on_single_line = false
73+
resharper_place_simple_embedded_statement_on_same_line = false
74+
resharper_place_simple_initializer_on_single_line = false
75+
resharper_place_simple_property_pattern_on_single_line = false
76+
resharper_use_indent_from_vs = false
77+
resharper_wrap_after_property_in_chained_method_calls = true
78+
resharper_wrap_array_initializer_style = chop_if_long
79+
resharper_wrap_chained_method_calls = chop_always
80+
resharper_wrap_linq_expressions = chop_always
81+
resharper_wrap_list_pattern = chop_if_long
82+
resharper_wrap_object_and_collection_initializer_style = chop_always
83+
resharper_wrap_property_pattern = chop_always
84+
85+
# ReSharper inspection severities
86+
resharper_arrange_redundant_parentheses_highlighting = hint
87+
resharper_arrange_this_qualifier_highlighting = hint
88+
resharper_arrange_type_member_modifiers_highlighting = hint
89+
resharper_arrange_type_modifiers_highlighting = hint
90+
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
91+
resharper_built_in_type_reference_style_highlighting = hint
92+
resharper_enforce_foreach_statement_braces_highlighting = warning
93+
resharper_enforce_for_statement_braces_highlighting = warning
94+
resharper_enforce_if_statement_braces_highlighting = warning
95+
resharper_enforce_lock_statement_braces_highlighting = warning
96+
resharper_enforce_using_statement_braces_highlighting = warning
97+
resharper_enforce_while_statement_braces_highlighting = warning
98+
resharper_mvc_action_not_resolved_highlighting = warning
99+
resharper_mvc_area_not_resolved_highlighting = warning
100+
resharper_mvc_controller_not_resolved_highlighting = warning
101+
resharper_mvc_masterpage_not_resolved_highlighting = warning
102+
resharper_mvc_partial_view_not_resolved_highlighting = warning
103+
resharper_mvc_template_not_resolved_highlighting = warning
104+
resharper_mvc_view_component_not_resolved_highlighting = warning
105+
resharper_mvc_view_component_view_not_resolved_highlighting = warning
106+
resharper_mvc_view_not_resolved_highlighting = warning
107+
resharper_razor_assembly_not_resolved_highlighting = warning
108+
resharper_redundant_base_qualifier_highlighting = warning
109+
resharper_web_config_module_not_resolved_highlighting = warning
110+
resharper_web_config_type_not_resolved_highlighting = warning
111+
resharper_web_config_wrong_module_highlighting = warning
112+
113+
[{*.har,*.jsb2,*.jsb3,*.json,*.jsonc,*.postman_collection,*.postman_collection.json,*.postman_environment,*.postman_environment.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,.ws-context,bowerrc,jest.config}]
114+
indent_style = space
115+
indent_size = 2
116+
117+
[{*.yaml,*.yml}]
118+
indent_style = space
119+
indent_size = 2
120+
121+
[*.cs]
122+
indent_style = space
123+
indent_size = 3
124+
tab_width = 3
125+
126+
[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,c++m,cc,ccm,cginc,compute,cp,cpp,cppm,cshtml,cu,cuh,cxx,cxxm,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,mxx,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,uxml,vb,xaml,xamlx,xoml,xsd}]
127+
indent_style = space
128+
indent_size = 4
129+
tab_width = 4
130+
131+
#########################
132+
# Custom added settings #
133+
#########################
134+
[*.cs]
135+
dotnet_diagnostic.cs8600.severity = error #Converting null literal or possible null value to non-nullable type.
136+
dotnet_diagnostic.cs8601.severity = error #Possible null reference assignment.
137+
dotnet_diagnostic.cs8602.severity = error #possible dereference of a null reference
138+
dotnet_diagnostic.cs8603.severity = error #possible null reference return
139+
dotnet_diagnostic.cs8604.severity = error #possible null reference argument for parameter
140+
dotnet_diagnostic.cs8605.severity = error #Unboxing a possibly null value
141+
dotnet_diagnostic.cs8618.severity = error # Non-nullable field is uninitialized. Consider declaring as nullable.
142+
dotnet_diagnostic.cs8625.severity = error # Cannot convert null literal to non-nullable reference type.
143+
dotnet_diagnostic.cs8762.severity = error # Nullability of reference types in type doesn't match overridden member.
144+
dotnet_diagnostic.cs1717.severity = error #variable is assigned to itself
145+
dotnet_diagnostic.cs1718.severity = error #comparison made to same variable
146+
dotnet_diagnostic.cs0659.severity = error #overriding object.Equals but not overriding object.GetHashCode
147+
dotnet_diagnostic.cs0251.severity = error #Indexing an array with a negative index (array indices always start at zero)
148+
dotnet_diagnostic.s3363.severity = none #Never set DateTime as PrimaryKey. Ignored as we never do it but have warnings for cache entities.
149+
dotnet_diagnostic.ca2016.severity = error #Forwarding cancellation tokens
150+
csharp_style_namespace_declarations = file_scoped:error
151+
resharper_entity_framework_model_validation_unlimited_string_length_highlighting = none
152+
153+
154+
#########################
155+
# VS added settings #
156+
#########################
157+
158+
[*.cs]
159+
csharp_style_namespace_declarations = file_scoped:error
160+
csharp_indent_labels = one_less_than_current
161+
csharp_using_directive_placement = outside_namespace:silent
162+
csharp_prefer_simple_using_statement = true:suggestion
163+
csharp_prefer_braces = true:silent
164+
csharp_style_prefer_method_group_conversion = true:silent
165+
csharp_style_prefer_top_level_statements = true:silent
166+
csharp_style_prefer_primary_constructors = true:suggestion
167+
csharp_style_expression_bodied_methods = false:silent
168+
csharp_style_expression_bodied_constructors = false:silent
169+
csharp_style_expression_bodied_operators = false:silent
170+
csharp_style_expression_bodied_properties = true:silent
171+
csharp_style_expression_bodied_indexers = true:silent
172+
csharp_style_expression_bodied_accessors = true:silent
173+
csharp_style_expression_bodied_lambdas = true:silent
174+
csharp_style_expression_bodied_local_functions = false:silent
175+
176+
[{*.yaml,*.yml}]
177+
dotnet_style_namespace_match_folder = true:suggestion
178+
dotnet_style_operator_placement_when_wrapping = beginning_of_line
179+
tab_width = 3
180+
dotnet_style_coalesce_expression = true:suggestion
181+
dotnet_style_null_propagation = true:suggestion
182+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
183+
dotnet_style_prefer_auto_properties = true:silent
184+
dotnet_style_object_initializer = true:suggestion
185+
dotnet_style_collection_initializer = true:suggestion
186+
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
187+
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
188+
189+
[*.csv]
190+
indent_style = tab
191+
tab_width = 4

Readme.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
**Pandatech.ResponseCrafter** is a comprehensive NuGet package for .NET 8+, specifically designed to enhance exception
66
handling and logging in ASP.NET Core applications, and now extended to support SignalR hubs. This package simplifies
77
managing standard and custom exceptions by crafting detailed error responses suitable for both development and
8-
production environments.
8+
production environments. It inherits all RFC 9457 Problem Details for HTTP APIs and even extends it.
99

1010
## Features
1111

@@ -26,30 +26,32 @@ production environments.
2626

2727
```json
2828
{
29-
"TraceId": "0HMVFE0A284AM:00000001",
30-
"Instance": "POST - 164.54.144.23:443/users/register",
31-
"StatusCode": 400,
32-
"Type": "BadRequestException",
33-
"Errors": {
34-
"email": "email_address_is_not_in_a_valid_format",
35-
"password": "password_must_be_at_least_8_characters_long"
36-
},
37-
"Message": "the_request_was_invalid_or_cannot_be_otherwise_served."
29+
"RequestId": "0HMVFE0A284AM:00000001",
30+
"TraceId": "a55582ab204162e66e124b0378776ab7",
31+
"Instance": "POST - 164.54.144.23:443/users/register",
32+
"StatusCode": 400,
33+
"Type": "BadRequestException",
34+
"Errors": {
35+
"email": "email_address_is_not_in_a_valid_format",
36+
"password": "password_must_be_at_least_8_characters_long"
37+
},
38+
"Message": "the_request_was_invalid_or_cannot_be_otherwise_served."
3839
}
3940
```
4041

4142
For SignalR, the standard error response format is:
4243

4344
```json
4445
{
45-
"InvocationId": "0HMVFE0A0HMVFE0A284AMHMV00HMVFE0A284AM0A284AM",
46-
"Instance": "SendMessage",
47-
"StatusCode": 400,
48-
"Errors": {
49-
"email": "email_address_is_not_in_a_valid_format",
50-
"password": "password_must_be_at_least_8_characters_long"
51-
},
52-
"Message": "the_request_was_invalid_or_cannot_be_otherwise_served."
46+
"TraceId": "a55582ab204162e66e124b0378776ab7",
47+
"InvocationId": "0HMVFE0A0HMVFE0A284AMHMV00HMVFE0A284AM0A284AM",
48+
"Instance": "SendMessage",
49+
"StatusCode": 400,
50+
"Errors": {
51+
"email": "email_address_is_not_in_a_valid_format",
52+
"password": "password_must_be_at_least_8_characters_long"
53+
},
54+
"Message": "the_request_was_invalid_or_cannot_be_otherwise_served."
5355
}
5456
```
5557

@@ -86,7 +88,7 @@ Configure visibility in your `appsettings.json`:
8688

8789
```json
8890
{
89-
"ResponseCrafterVisibility": "Public"
91+
"ResponseCrafterVisibility": "Public"
9092
}
9193
```
9294

ResponseCrafter.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1010
.gitignore = .gitignore
1111
Readme.md = Readme.md
1212
global.json = global.json
13+
.editorconfig = .editorconfig
1314
EndProjectSection
1415
EndProject
1516
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C43D3C79-62B4-43AC-A166-F64BC869D0E9}"

src/ResponseCrafter/ApiExceptionHandler.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using FluentImporter.Exceptions;
1+
using System.Diagnostics;
2+
using FluentImporter.Exceptions;
23
using GridifyExtensions.Exceptions;
34
using Microsoft.AspNetCore.Http;
45
using Microsoft.Extensions.Logging;
@@ -144,7 +145,8 @@ private async Task HandleApiExceptionAsync(HttpContext httpContext, ApiException
144145
{
145146
var response = new ErrorResponse
146147
{
147-
TraceId = httpContext.TraceIdentifier,
148+
RequestId = httpContext.TraceIdentifier,
149+
TraceId = Activity.Current?.RootId ?? "",
148150
Instance = CreateRequestPath(httpContext),
149151
StatusCode = exception.StatusCode,
150152
Type = exception.GetType().Name,
@@ -173,7 +175,8 @@ private async Task HandleGeneralExceptionAsync(HttpContext httpContext, Exceptio
173175

174176
var response = new ErrorResponse
175177
{
176-
TraceId = httpContext.TraceIdentifier,
178+
RequestId = httpContext.TraceIdentifier,
179+
TraceId = Activity.Current?.RootId ?? "",
177180
Instance = CreateRequestPath(httpContext),
178181
StatusCode = 500,
179182
Type = "InternalServerError",

src/ResponseCrafter/Dtos/ErrorResponse.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
public class ErrorResponse
44
{
5-
public string TraceId { get; set; } = null!;
6-
public string Instance { get; set; } = null!;
7-
public int StatusCode { get; set; }
8-
public string Type { get; set; } = null!;
9-
public Dictionary<string, string>? Errors { get; set; }
10-
public string Message { get; set; } = null!;
5+
public required string RequestId { get; set; }
6+
public required string TraceId { get; set; }
7+
public required string Instance { get; set; }
8+
public int StatusCode { get; init; }
9+
public required string Type { get; set; }
10+
public Dictionary<string, string>? Errors { get; set; }
11+
public required string Message { get; set; }
1112
}

src/ResponseCrafter/Dtos/HubErrorResponse.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/// </summary>
66
public class HubErrorResponse
77
{
8+
public required string TraceId { get; set; }
89
public required string InvocationId { get; set; }
910
public required string Instance { get; set; }
1011
public int StatusCode { get; set; }

src/ResponseCrafter/ResponseCrafter.csproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
<Copyright>MIT</Copyright>
99
<PackageIcon>pandatech.png</PackageIcon>
1010
<PackageReadmeFile>Readme.md</PackageReadmeFile>
11-
<Version>4.0.0</Version>
11+
<Version>4.0.1</Version>
1212
<PackageId>Pandatech.ResponseCrafter</PackageId>
1313
<PackageTags>Pandatech, library, exception handler, exception, middleware, Api response</PackageTags>
1414
<Title>ResponseCrafter</Title>
1515
<Description>Handling exceptions, custom Dtos.</Description>
1616
<RepositoryUrl>https://github.com/PandaTechAM/be-lib-response-crafter</RepositoryUrl>
17-
<PackageReleaseNotes>SignalR ResponseCrafting Support Has Been Added</PackageReleaseNotes>
17+
<PackageReleaseNotes>TraceId now shows real traceId. Before it was requestId. For RequestId new property has been added.</PackageReleaseNotes>
1818
</PropertyGroup>
1919

2020
<ItemGroup>
@@ -23,12 +23,12 @@
2323
</ItemGroup>
2424

2525
<ItemGroup>
26-
<PackageReference Include="Humanizer" Version="2.14.1" />
27-
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
28-
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.8" />
29-
<PackageReference Include="PandaTech.FluentImporter" Version="2.0.13" />
30-
<PackageReference Include="Pandatech.GridifyExtensions" Version="1.6.2" />
31-
<PackageReference Include="PandaTech.ServiceResponse" Version="1.2.12" />
26+
<PackageReference Include="Humanizer" Version="2.14.1"/>
27+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8"/>
28+
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.8"/>
29+
<PackageReference Include="PandaTech.FluentImporter" Version="2.0.13"/>
30+
<PackageReference Include="Pandatech.GridifyExtensions" Version="1.6.2"/>
31+
<PackageReference Include="PandaTech.ServiceResponse" Version="1.2.12"/>
3232
</ItemGroup>
3333

3434
</Project>

src/ResponseCrafter/SignalRExceptionFilter.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using GridifyExtensions.Exceptions;
1+
using System.Diagnostics;
2+
using GridifyExtensions.Exceptions;
23
using Microsoft.AspNetCore.SignalR;
34
using Microsoft.EntityFrameworkCore;
45
using Microsoft.Extensions.Configuration;
@@ -96,11 +97,12 @@ private async Task<HubErrorResponse> HandleApiExceptionAsync(HubInvocationContex
9697
{
9798
var response = new HubErrorResponse
9899
{
100+
TraceId = Activity.Current?.RootId ?? "",
99101
InvocationId = invocationId,
100102
Instance = invocationContext.HubMethodName,
101103
StatusCode = exception.StatusCode,
102104
Message = exception.Message.ConvertCase(_convention),
103-
Errors = exception.Errors
105+
Errors = exception.Errors,
104106
};
105107

106108
if (response.Errors is null || response.Errors.Count == 0)
@@ -124,6 +126,7 @@ private async Task<HubErrorResponse> HandleGeneralExceptionAsync(HubInvocationCo
124126

125127
var response = new HubErrorResponse
126128
{
129+
TraceId = Activity.Current?.RootId ?? "",
127130
InvocationId = invocationId,
128131
Instance = invocationContext.HubMethodName,
129132
StatusCode = 500,

test/ResponseCrafter.Demo/Hubs/ChatHub.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ public async Task SendMessage(HubArgument<Message> hubArgument)
2222
public class Message
2323
{
2424
public required string User { get; set; }
25-
public string Content { get; set; }
25+
public required string Content { get; set; }
2626
}

0 commit comments

Comments
 (0)