Reading SQL query from a resource, with error logging
I've created a utility class that expects a logger to be passed at a method level, since I prefer legitimate errors to be written out for troubleshooting later on. Another developer hates passing the logger to the method, because he does not care.
- Cannot use optional attribute, since
ILogger
is not a constant. - Cannot use
params
because it would be a singleton, not a collection.
So I implemented it in the following manner:
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
return reader.ReadToEnd();
}
catch(Exception exception)
{
logger.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw new Exception(exception.Message);
}
}
}
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it? Or would there be a better way to handle this?
c# error-handling logging .net-core
add a comment |
I've created a utility class that expects a logger to be passed at a method level, since I prefer legitimate errors to be written out for troubleshooting later on. Another developer hates passing the logger to the method, because he does not care.
- Cannot use optional attribute, since
ILogger
is not a constant. - Cannot use
params
because it would be a singleton, not a collection.
So I implemented it in the following manner:
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
return reader.ReadToEnd();
}
catch(Exception exception)
{
logger.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw new Exception(exception.Message);
}
}
}
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it? Or would there be a better way to handle this?
c# error-handling logging .net-core
1
I think this question leads to a much bigger problem. You need a standard. This kind of thing can't be half implemented in your system when you add it and your other dev. doesn't. Although I believe 200_success's answer covers your specific problem very well.
– IEatBagels
Dec 4 at 18:21
add a comment |
I've created a utility class that expects a logger to be passed at a method level, since I prefer legitimate errors to be written out for troubleshooting later on. Another developer hates passing the logger to the method, because he does not care.
- Cannot use optional attribute, since
ILogger
is not a constant. - Cannot use
params
because it would be a singleton, not a collection.
So I implemented it in the following manner:
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
return reader.ReadToEnd();
}
catch(Exception exception)
{
logger.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw new Exception(exception.Message);
}
}
}
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it? Or would there be a better way to handle this?
c# error-handling logging .net-core
I've created a utility class that expects a logger to be passed at a method level, since I prefer legitimate errors to be written out for troubleshooting later on. Another developer hates passing the logger to the method, because he does not care.
- Cannot use optional attribute, since
ILogger
is not a constant. - Cannot use
params
because it would be a singleton, not a collection.
So I implemented it in the following manner:
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
return reader.ReadToEnd();
}
catch(Exception exception)
{
logger.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw new Exception(exception.Message);
}
}
}
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it? Or would there be a better way to handle this?
c# error-handling logging .net-core
c# error-handling logging .net-core
edited Dec 4 at 17:14
200_success
128k15150412
128k15150412
asked Dec 4 at 16:59
Greg
43038
43038
1
I think this question leads to a much bigger problem. You need a standard. This kind of thing can't be half implemented in your system when you add it and your other dev. doesn't. Although I believe 200_success's answer covers your specific problem very well.
– IEatBagels
Dec 4 at 18:21
add a comment |
1
I think this question leads to a much bigger problem. You need a standard. This kind of thing can't be half implemented in your system when you add it and your other dev. doesn't. Although I believe 200_success's answer covers your specific problem very well.
– IEatBagels
Dec 4 at 18:21
1
1
I think this question leads to a much bigger problem. You need a standard. This kind of thing can't be half implemented in your system when you add it and your other dev. doesn't. Although I believe 200_success's answer covers your specific problem very well.
– IEatBagels
Dec 4 at 18:21
I think this question leads to a much bigger problem. You need a standard. This kind of thing can't be half implemented in your system when you add it and your other dev. doesn't. Although I believe 200_success's answer covers your specific problem very well.
– IEatBagels
Dec 4 at 18:21
add a comment |
2 Answers
2
active
oldest
votes
The most unforgivable aspect of this code is that it rethrows a degraded exception. The original type of the exception (likely an IOException
) and the stack trace information are lost when you throw new Exception(…)
.
Two acceptable approaches are:
Log the failure (if a non-null
logger
was passed). Then re-throw the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}.{Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
Throw a custom exception, wrapping the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
throw new EmbeddedResourceException($"Failed to read query file {namespaceAndFileNameWithExtension}", exception);
}
}
In this case, requiring an
ILogger
just isn't worth it. The caller has all of the information in theEmbeddedResourceException
, and can log it if it wants.
I recommend the second approach, because it respects the principle of separation of concerns.
but the exception would be logged to the event viewer instead of an application specific log file, which does require extra investigation and more information to find the thrown event though correct?
– Greg
Dec 4 at 17:43
1
Who calls thisGetSqlQuery()
function? At some point, some caller in the stack should catch the exception and handle it in the way that you want.
– 200_success
Dec 4 at 17:45
Their implemented context class where they read the query resources, so they should be actually handling any exceptions at that point or when they call their context. To know if something failed to enter the database.
– Greg
Dec 4 at 17:48
add a comment |
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it?
If I wouldn't want to pass an
ILogger
I would just pass(ILogger)null
and your method would throw aNullReferenceException
if an exception occurs. If you use C# 6 you could use the Null-conditional operatorIf you keep the method signature like posted anyone who uses this method needs to pass an
ILogger
. To overcome this problem you can either make theILogger
argument optional or you implement an overloaded version of this method which doesn't take anILogger
argument.Omitting braces althought they might be optional should be avoided.
Throwing
throw new Exception(exception.Message)
will destroy the stacktrace. It would be better to justthrow
.By using the ctor of
StreamReader
which only takes aStream
as argument the default encoding is UTF8Encoding.
Implementing the mentioned points would lead to
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
return GetSqlQuery(namespaceAndFileNameWithExtension, (ILogger)null);
}
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
catch(Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
}
In C# 8 when they introduce nothing is null by default unless explicit, would that change your expectation?
– Greg
Dec 4 at 17:49
Well I did't inform me about C# 8. I usually only work with what is avaible.
– Heslacher
Dec 4 at 17:50
Oh, fair enough. I just know the paradigm for C# is about to shift. I know the feature is an opt-in, but in essence with the current way everything is null since a state has not been defined, in C# 8 nothing can be assigned as null unless the type explicitly allows it. So I was just curious if that would change your answer or you think this is still the best course of action? I am not trying to demean or dismiss your current answer, simply want to get the most information so I may make the best decision possible for implementation.
– Greg
Dec 4 at 17:52
Why not use an optional parameter on theILogger
instead of an overload?
– IEatBagels
Dec 4 at 18:22
Because using an overloaded method is ckearer from the caller side.
– Heslacher
Dec 4 at 18:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209007%2freading-sql-query-from-a-resource-with-error-logging%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
The most unforgivable aspect of this code is that it rethrows a degraded exception. The original type of the exception (likely an IOException
) and the stack trace information are lost when you throw new Exception(…)
.
Two acceptable approaches are:
Log the failure (if a non-null
logger
was passed). Then re-throw the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}.{Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
Throw a custom exception, wrapping the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
throw new EmbeddedResourceException($"Failed to read query file {namespaceAndFileNameWithExtension}", exception);
}
}
In this case, requiring an
ILogger
just isn't worth it. The caller has all of the information in theEmbeddedResourceException
, and can log it if it wants.
I recommend the second approach, because it respects the principle of separation of concerns.
but the exception would be logged to the event viewer instead of an application specific log file, which does require extra investigation and more information to find the thrown event though correct?
– Greg
Dec 4 at 17:43
1
Who calls thisGetSqlQuery()
function? At some point, some caller in the stack should catch the exception and handle it in the way that you want.
– 200_success
Dec 4 at 17:45
Their implemented context class where they read the query resources, so they should be actually handling any exceptions at that point or when they call their context. To know if something failed to enter the database.
– Greg
Dec 4 at 17:48
add a comment |
The most unforgivable aspect of this code is that it rethrows a degraded exception. The original type of the exception (likely an IOException
) and the stack trace information are lost when you throw new Exception(…)
.
Two acceptable approaches are:
Log the failure (if a non-null
logger
was passed). Then re-throw the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}.{Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
Throw a custom exception, wrapping the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
throw new EmbeddedResourceException($"Failed to read query file {namespaceAndFileNameWithExtension}", exception);
}
}
In this case, requiring an
ILogger
just isn't worth it. The caller has all of the information in theEmbeddedResourceException
, and can log it if it wants.
I recommend the second approach, because it respects the principle of separation of concerns.
but the exception would be logged to the event viewer instead of an application specific log file, which does require extra investigation and more information to find the thrown event though correct?
– Greg
Dec 4 at 17:43
1
Who calls thisGetSqlQuery()
function? At some point, some caller in the stack should catch the exception and handle it in the way that you want.
– 200_success
Dec 4 at 17:45
Their implemented context class where they read the query resources, so they should be actually handling any exceptions at that point or when they call their context. To know if something failed to enter the database.
– Greg
Dec 4 at 17:48
add a comment |
The most unforgivable aspect of this code is that it rethrows a degraded exception. The original type of the exception (likely an IOException
) and the stack trace information are lost when you throw new Exception(…)
.
Two acceptable approaches are:
Log the failure (if a non-null
logger
was passed). Then re-throw the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}.{Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
Throw a custom exception, wrapping the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
throw new EmbeddedResourceException($"Failed to read query file {namespaceAndFileNameWithExtension}", exception);
}
}
In this case, requiring an
ILogger
just isn't worth it. The caller has all of the information in theEmbeddedResourceException
, and can log it if it wants.
I recommend the second approach, because it respects the principle of separation of concerns.
The most unforgivable aspect of this code is that it rethrows a degraded exception. The original type of the exception (likely an IOException
) and the stack trace information are lost when you throw new Exception(…)
.
Two acceptable approaches are:
Log the failure (if a non-null
logger
was passed). Then re-throw the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}.{Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
Throw a custom exception, wrapping the original exception.
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
catch (Exception exception)
{
throw new EmbeddedResourceException($"Failed to read query file {namespaceAndFileNameWithExtension}", exception);
}
}
In this case, requiring an
ILogger
just isn't worth it. The caller has all of the information in theEmbeddedResourceException
, and can log it if it wants.
I recommend the second approach, because it respects the principle of separation of concerns.
edited Dec 4 at 20:36
answered Dec 4 at 17:38
200_success
128k15150412
128k15150412
but the exception would be logged to the event viewer instead of an application specific log file, which does require extra investigation and more information to find the thrown event though correct?
– Greg
Dec 4 at 17:43
1
Who calls thisGetSqlQuery()
function? At some point, some caller in the stack should catch the exception and handle it in the way that you want.
– 200_success
Dec 4 at 17:45
Their implemented context class where they read the query resources, so they should be actually handling any exceptions at that point or when they call their context. To know if something failed to enter the database.
– Greg
Dec 4 at 17:48
add a comment |
but the exception would be logged to the event viewer instead of an application specific log file, which does require extra investigation and more information to find the thrown event though correct?
– Greg
Dec 4 at 17:43
1
Who calls thisGetSqlQuery()
function? At some point, some caller in the stack should catch the exception and handle it in the way that you want.
– 200_success
Dec 4 at 17:45
Their implemented context class where they read the query resources, so they should be actually handling any exceptions at that point or when they call their context. To know if something failed to enter the database.
– Greg
Dec 4 at 17:48
but the exception would be logged to the event viewer instead of an application specific log file, which does require extra investigation and more information to find the thrown event though correct?
– Greg
Dec 4 at 17:43
but the exception would be logged to the event viewer instead of an application specific log file, which does require extra investigation and more information to find the thrown event though correct?
– Greg
Dec 4 at 17:43
1
1
Who calls this
GetSqlQuery()
function? At some point, some caller in the stack should catch the exception and handle it in the way that you want.– 200_success
Dec 4 at 17:45
Who calls this
GetSqlQuery()
function? At some point, some caller in the stack should catch the exception and handle it in the way that you want.– 200_success
Dec 4 at 17:45
Their implemented context class where they read the query resources, so they should be actually handling any exceptions at that point or when they call their context. To know if something failed to enter the database.
– Greg
Dec 4 at 17:48
Their implemented context class where they read the query resources, so they should be actually handling any exceptions at that point or when they call their context. To know if something failed to enter the database.
– Greg
Dec 4 at 17:48
add a comment |
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it?
If I wouldn't want to pass an
ILogger
I would just pass(ILogger)null
and your method would throw aNullReferenceException
if an exception occurs. If you use C# 6 you could use the Null-conditional operatorIf you keep the method signature like posted anyone who uses this method needs to pass an
ILogger
. To overcome this problem you can either make theILogger
argument optional or you implement an overloaded version of this method which doesn't take anILogger
argument.Omitting braces althought they might be optional should be avoided.
Throwing
throw new Exception(exception.Message)
will destroy the stacktrace. It would be better to justthrow
.By using the ctor of
StreamReader
which only takes aStream
as argument the default encoding is UTF8Encoding.
Implementing the mentioned points would lead to
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
return GetSqlQuery(namespaceAndFileNameWithExtension, (ILogger)null);
}
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
catch(Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
}
In C# 8 when they introduce nothing is null by default unless explicit, would that change your expectation?
– Greg
Dec 4 at 17:49
Well I did't inform me about C# 8. I usually only work with what is avaible.
– Heslacher
Dec 4 at 17:50
Oh, fair enough. I just know the paradigm for C# is about to shift. I know the feature is an opt-in, but in essence with the current way everything is null since a state has not been defined, in C# 8 nothing can be assigned as null unless the type explicitly allows it. So I was just curious if that would change your answer or you think this is still the best course of action? I am not trying to demean or dismiss your current answer, simply want to get the most information so I may make the best decision possible for implementation.
– Greg
Dec 4 at 17:52
Why not use an optional parameter on theILogger
instead of an overload?
– IEatBagels
Dec 4 at 18:22
Because using an overloaded method is ckearer from the caller side.
– Heslacher
Dec 4 at 18:32
add a comment |
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it?
If I wouldn't want to pass an
ILogger
I would just pass(ILogger)null
and your method would throw aNullReferenceException
if an exception occurs. If you use C# 6 you could use the Null-conditional operatorIf you keep the method signature like posted anyone who uses this method needs to pass an
ILogger
. To overcome this problem you can either make theILogger
argument optional or you implement an overloaded version of this method which doesn't take anILogger
argument.Omitting braces althought they might be optional should be avoided.
Throwing
throw new Exception(exception.Message)
will destroy the stacktrace. It would be better to justthrow
.By using the ctor of
StreamReader
which only takes aStream
as argument the default encoding is UTF8Encoding.
Implementing the mentioned points would lead to
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
return GetSqlQuery(namespaceAndFileNameWithExtension, (ILogger)null);
}
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
catch(Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
}
In C# 8 when they introduce nothing is null by default unless explicit, would that change your expectation?
– Greg
Dec 4 at 17:49
Well I did't inform me about C# 8. I usually only work with what is avaible.
– Heslacher
Dec 4 at 17:50
Oh, fair enough. I just know the paradigm for C# is about to shift. I know the feature is an opt-in, but in essence with the current way everything is null since a state has not been defined, in C# 8 nothing can be assigned as null unless the type explicitly allows it. So I was just curious if that would change your answer or you think this is still the best course of action? I am not trying to demean or dismiss your current answer, simply want to get the most information so I may make the best decision possible for implementation.
– Greg
Dec 4 at 17:52
Why not use an optional parameter on theILogger
instead of an overload?
– IEatBagels
Dec 4 at 18:22
Because using an overloaded method is ckearer from the caller side.
– Heslacher
Dec 4 at 18:32
add a comment |
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it?
If I wouldn't want to pass an
ILogger
I would just pass(ILogger)null
and your method would throw aNullReferenceException
if an exception occurs. If you use C# 6 you could use the Null-conditional operatorIf you keep the method signature like posted anyone who uses this method needs to pass an
ILogger
. To overcome this problem you can either make theILogger
argument optional or you implement an overloaded version of this method which doesn't take anILogger
argument.Omitting braces althought they might be optional should be avoided.
Throwing
throw new Exception(exception.Message)
will destroy the stacktrace. It would be better to justthrow
.By using the ctor of
StreamReader
which only takes aStream
as argument the default encoding is UTF8Encoding.
Implementing the mentioned points would lead to
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
return GetSqlQuery(namespaceAndFileNameWithExtension, (ILogger)null);
}
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
catch(Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
}
Would be incorrect to expect someone to pass an ILogger even if they do not intend to use it?
If I wouldn't want to pass an
ILogger
I would just pass(ILogger)null
and your method would throw aNullReferenceException
if an exception occurs. If you use C# 6 you could use the Null-conditional operatorIf you keep the method signature like posted anyone who uses this method needs to pass an
ILogger
. To overcome this problem you can either make theILogger
argument optional or you implement an overloaded version of this method which doesn't take anILogger
argument.Omitting braces althought they might be optional should be avoided.
Throwing
throw new Exception(exception.Message)
will destroy the stacktrace. It would be better to justthrow
.By using the ctor of
StreamReader
which only takes aStream
as argument the default encoding is UTF8Encoding.
Implementing the mentioned points would lead to
public static class EmbeddedResourceUtility
{
public static string GetSqlQuery(string namespaceAndFileNameWithExtension)
{
return GetSqlQuery(namespaceAndFileNameWithExtension, (ILogger)null);
}
public static string GetSqlQuery(string namespaceAndFileNameWithExtension, ILogger logger)
{
try
{
using(var stream = typeof(EmbeddedResourceUtility).GetTypeInfo().Assembly.GetManifestResourceStream(namespaceAndFileNameWithExtension))
using(var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
catch(Exception exception)
{
logger?.Error($"Failed to read query file {namespaceAndFileNameWithExtension}. {Environment.NewLine}{exception.HResult}: {exception.Message}");
throw;
}
}
}
answered Dec 4 at 17:31
Heslacher
44.9k460155
44.9k460155
In C# 8 when they introduce nothing is null by default unless explicit, would that change your expectation?
– Greg
Dec 4 at 17:49
Well I did't inform me about C# 8. I usually only work with what is avaible.
– Heslacher
Dec 4 at 17:50
Oh, fair enough. I just know the paradigm for C# is about to shift. I know the feature is an opt-in, but in essence with the current way everything is null since a state has not been defined, in C# 8 nothing can be assigned as null unless the type explicitly allows it. So I was just curious if that would change your answer or you think this is still the best course of action? I am not trying to demean or dismiss your current answer, simply want to get the most information so I may make the best decision possible for implementation.
– Greg
Dec 4 at 17:52
Why not use an optional parameter on theILogger
instead of an overload?
– IEatBagels
Dec 4 at 18:22
Because using an overloaded method is ckearer from the caller side.
– Heslacher
Dec 4 at 18:32
add a comment |
In C# 8 when they introduce nothing is null by default unless explicit, would that change your expectation?
– Greg
Dec 4 at 17:49
Well I did't inform me about C# 8. I usually only work with what is avaible.
– Heslacher
Dec 4 at 17:50
Oh, fair enough. I just know the paradigm for C# is about to shift. I know the feature is an opt-in, but in essence with the current way everything is null since a state has not been defined, in C# 8 nothing can be assigned as null unless the type explicitly allows it. So I was just curious if that would change your answer or you think this is still the best course of action? I am not trying to demean or dismiss your current answer, simply want to get the most information so I may make the best decision possible for implementation.
– Greg
Dec 4 at 17:52
Why not use an optional parameter on theILogger
instead of an overload?
– IEatBagels
Dec 4 at 18:22
Because using an overloaded method is ckearer from the caller side.
– Heslacher
Dec 4 at 18:32
In C# 8 when they introduce nothing is null by default unless explicit, would that change your expectation?
– Greg
Dec 4 at 17:49
In C# 8 when they introduce nothing is null by default unless explicit, would that change your expectation?
– Greg
Dec 4 at 17:49
Well I did't inform me about C# 8. I usually only work with what is avaible.
– Heslacher
Dec 4 at 17:50
Well I did't inform me about C# 8. I usually only work with what is avaible.
– Heslacher
Dec 4 at 17:50
Oh, fair enough. I just know the paradigm for C# is about to shift. I know the feature is an opt-in, but in essence with the current way everything is null since a state has not been defined, in C# 8 nothing can be assigned as null unless the type explicitly allows it. So I was just curious if that would change your answer or you think this is still the best course of action? I am not trying to demean or dismiss your current answer, simply want to get the most information so I may make the best decision possible for implementation.
– Greg
Dec 4 at 17:52
Oh, fair enough. I just know the paradigm for C# is about to shift. I know the feature is an opt-in, but in essence with the current way everything is null since a state has not been defined, in C# 8 nothing can be assigned as null unless the type explicitly allows it. So I was just curious if that would change your answer or you think this is still the best course of action? I am not trying to demean or dismiss your current answer, simply want to get the most information so I may make the best decision possible for implementation.
– Greg
Dec 4 at 17:52
Why not use an optional parameter on the
ILogger
instead of an overload?– IEatBagels
Dec 4 at 18:22
Why not use an optional parameter on the
ILogger
instead of an overload?– IEatBagels
Dec 4 at 18:22
Because using an overloaded method is ckearer from the caller side.
– Heslacher
Dec 4 at 18:32
Because using an overloaded method is ckearer from the caller side.
– Heslacher
Dec 4 at 18:32
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209007%2freading-sql-query-from-a-resource-with-error-logging%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I think this question leads to a much bigger problem. You need a standard. This kind of thing can't be half implemented in your system when you add it and your other dev. doesn't. Although I believe 200_success's answer covers your specific problem very well.
– IEatBagels
Dec 4 at 18:21