I use IErrorHandler in my project for handle exceptions.
But how can i log incoming method parameter with exception.
I want to get Request parameter for logging.
Sample Method:
public Response GetData(Request request) {
return new Response();
}
You could get the request message like this:
Message requestMessage = OperationContext.Current.RequestContext.RequestMessage;
What I do usually is to log the entire request XML.
You don't have such information in IErrorHandler - you can only parse raw message in ProvideFault method.
You can try to use another approach - implement custom IOperationInvoker and in Invoke method do something like:
// Just synchronous implementation - for asynchronous handle InvokeBegin and InvokeEnd
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
try
{
// Run common invoker - you will create new Invoker as decorator for existing one.
return innerInvoker.Invoke(instance, inputs, outputs);
}
catch(Exception e)
{
// Handle error here
}
}
Operation invoker is responsible for selection correct operation in service and ivoke it. It is just idea - I haven't tested it.
Two ways:
The native WCF logger will capture all requests & responses when set to verbose however, these files tend to get real big, real quick.
Use log4net (search google to download)
private static readonly ILog log = LogManager.GetLogger(typeof(MyClass));
public class MyClass
{
...
public Foo DoSomething(string arg)
{
try
{
//do something
}
catch(Exception e)
{
log.error(string.format("{0} Arguements: {1}", e.Tostring(), arg);
}
}
}
Related
I have a service method that does so many things.
public Result DoSomething(){
var queryResult = service.GetResult();
SaveResultToRedis(queryResult);
logger.Log($"this data saved in redis successfully {queryResult.Id}");
AddSomethingToKafka(queryResult);
logger.Log($"this data saved in kafka successfully {queryResult.Id}");
logger.Log($"this data response is success {queryResult.Id}");
}
In this stuation,
if redis or kafka fails, the request response will fail.
if logger service fails, the request response will fail.
if I put all logics in try catch blocks, code will appear so bad.
Which way may apply in this stuations? Is there any design pattern approaches or else?
If you want to try to make your method thinner, then try to apply SOLID rules.
If DoSomething() method just saves data to some database or event system, then we can separate them by database or event systems. However, code example just saves in two places and it would not be great choice separate by storage.
As an alterantive, it is possible to hide logger.log methods by creating a private helper method and call it from DoSomething():
private void ExecuteAndLog(Action action, logger, string message)
{
action();
logger.log(message);
}
and the full code looks like this:
public void SaveToKafka(string str)
{
}
public void SaveToRedis(string str)
{
}
public void DoSomething()
{
try
{
string s1 = "s1";
ExecuteAndLog(() => SaveToKafka(s1), logger, "someMessage");
ExecuteAndLog(() => SaveToRedis(s1), logger, "someMessage");
logger.log("this data response is success");
}
catch (Exception)
{
throw;
}
}
private void ExecuteAndLog(Action action, logger, string message)
{
action();
logger.log(message);
}
I have a WCF service which has basicHttp endpoints exposed. The issue is reported in PEN testing that service accepts strings containing script tags and returns the strings with script tag which when directly used in web apps consuming it causes XSS attack.
What I can do is in every operation implementation write a code to make the strings script proof. But is there any easy/efficient way so that I can write a single code to clean all the incoming strings in WCF calls from script tags.
e.g. in AddUser operation which takes username and address, if I submit Akshay<script>alert('hi');</script>, the operation just should remove script tags.
So currently it is returning Akshay<script>alert('hi');</script> but is expected to return something like Akshayalert('hi');
You can implement your own operation invoker:
public class CleanOperationInvoker:IOperationInvoker
{
private readonly IOperationInvoker _invoker;
public CacheOperationInvoker(IOperationInvoker invoker)
{
_invoker = invoker;
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
inputs = CleanInputs(inputs);
return _invoker.Invoke(instance, inputs, out outputs);
}
private static object[] CleanInputs(object[] inputs)
{
for(int i = 0; i < inputs.Length;i++)
{
var str = inputs[i] as string;
if(!string.IsNullOrEmpty(str))
inputs[i] = StripHTML(str);
}
return inputs;
}
public static string StripHTML(string input)
{
return Regex.Replace(input, "<.*?>", String.Empty);
}
}
Then implement behavior:
public class CleanOperationBehavior: Attribute, IOperationBehavior
{
public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
{
//Putting ourself in between dispatching invoker
dispatchOperation.Invoker = new CleanOperationInvoker(dispatchOperation.Invoker);
}
}
Then just use it like this:
[ServiceContract]
public interface IHackMeService
{
[OperationContract]
[CleanOperationBehavior]
int Get(string hack, string me, int beach);
}
Or you can implement endpoint behavior and attach it to all of your operations on all contracts. This way, by the way, you can even reject operation if it contains invalid strings. Just throw exception or something.
I has not compiled it, so if you meet any errors you can tell me and I will update my answer.
There is so called message interceptor for wcf wherein you can intercept every incomming and outgoing request prior to the actual target operation. It's perfect implementation if you want to validate messages without annotating every operation. It's pretty easy to implement and hook up on your service.
This PENtest finding is not only resposibility of your service but also the app that will consume the result.
Note : Sometimes PENtest result could be false positive specialy if both app can handle input without harm :)
Objective is to unit test a PUBLIC VOID Method.
I have a mocked service, which my class-under-test would call, in a for-each loop with 3 different parameters.
The class-under-test passes some input parameters to "SendRequest" method of the service which executes using those parameters.
I want the mocked service to throw an exception when one of the parameters has a specific value e.g "abc".
I use something like this:
public class ClassUnderTest
{
private IMyService _myservice;
public ClassUnderTest(IMyService myservice)
{
_myservice = myservice;
}
public void MyMethod()
{
//assume I get those 3 values from somewhere, in here.
var list = new List<string>{"abc","aaa","bbb"};
foreach(var item in list)
{
try
{
_myservice.SendRequest(item);
}
catch(Exception ex)
{
//do some logging and continue calling service with next item in list
}
}
}
}
var myService = new Mock<IMyService>();
myService.Setup(x => x.SendRequest("abc")).Throws<Exception>();
myService.Setup(x => x.SendRequest("aaa"));
myService.Setup(x => x.SendRequest("bbb"));
var classUnderTest = new ClassUnderTest(myService.Object);
classUnderTest.MyMethod();
myService.Verify(x =>x.SendRequest(It.IsAny<string>()), Times.Exactly(2));
More Context:
As MyMethod returns void, to test it, I can only rely on the the fact that my dependencies were invoked at different portions of the code in this method. For e.g. if there is a null check for input parameters before service call, the method would return before it invokes the service. If it goes past null check, the dependency service would be invoked. I would be able to trace these in the code coverage results( and in debug mode).
When I run the test, it fails because its invoking the service thrice but I expect the invocation to happen twice(now may be I am wrong and may be that although it is supposed to throw exception the invocation attempt is still counted by Verify call and hence I get 3 runs).
Whatever be the case, on debug I see that the service never throws exception. I have a try-catch in the for-each-loop where I want to do some logging and continue calling the service again with the next value. But I never get to get inside the Catch block.
What am I doing wrong?
Option 1: Specific Exception
My 1st suggestion would throw a more specific exception so you can be more sure.
Option 2: Inject an ILogger service
Refactor out the logging into an ILogger and inject that in. Then pass a mock of that in and assert against it.
Option 3: Extract and Override
If you must check catch block was hit you can use extract and override:
public class ClassUnderTest
{
private IMyService _myservice;
public ClassUnderTest(IMyService myservice)
{
_myservice = myservice;
}
public void MyMethod()
{
//assume I get those 3 values from somewhere, in here.
var list = new List<string>{"abc","aaa","bbb"};
foreach(var item in list)
{
try
{
_myservice.SendRequest(item);
}
catch(Exception ex)
{
LogError(ex);
}
}
}
protected virtual LogException(Exception ex)
{
//do logging
}
}
public class TestableClassUnderTest : ClassUnderTest
{
public bool LoggingWasCalled { get; set; }
protected virtual LogException(Exception ex)
{
LoggingWasCalled = true;
}
}
Then you could sheck something like this:
var testableSut = new TestableClassUnderTest ();
testableSut.MyMethod("abc");
Assert.True(testableSut.LoggingWasCalled);
I walk through it in more detail here: http://devonburriss.me/testing-the-untestable/
My DAL doesn't handle exceptions and it will be propagated up to the calling method in the presenter classes where the exception will be handled.
I'm using a single handler called ExecutAction(Action action) so I'm catching exceptions in one place rather than repeating in every method.
At the moment, I'm not logging errors. Just alert the user for an action and try to keep the system alive if possible.
When showing messages to users, Presenters will use a static class called MessagingService. (ShowErrorMessage()). So that I can customize all massage boxes in one place.
private void Search()
{
ExecutAction(() =>
{
var info = _DataService.GetByACNo(_model.AccountNumber);
if (info != null)
{
_Model = info ;
this.SetViewPropertiesFromModel(_Model, _View);
}
else
{
MessageBox.Show ("Bank account not found");
}
});
}
private void ExecutAction(Action action)
{
try
{
action();
}
catch (NullReferenceException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlTypes.SqlTypeException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlClient.SqlException e) { MessagingService.ShowErrorMessage(e.Message); }
}
}
Should I include general exception handler to this, to be able to handle any unforeseen exceptions?
Also could you show me a better way to handle showing messages than using a static?
Does use of lambda statements in every method call (ExecutAction(() =>) degrade code readability?
When showing user messages how to show a custom message like "Check the server connection" etc. first and then if the user wants more information (like StackTrace / technical details) he /she could press a button like More Info which is in the MessageBox dialog?
I agree with jeffrey about trying to incorporate IoC for your message service. You could define an abstract base presenter class that has a dependency on an interface for your message service. The base class would be responsible for handling the delegate execution + exception logging.
public interface IMessageService
{
void ShowErrorMessage(Exception e);
}
public abstract class PresenterBase
{
private readonly IMessageService _messageService;
public PresenterBase(IMessageService messageService)
{
this._messageService = messageService;
}
protected void ExecuteAction(Action action)
{
try
{
action();
}
catch (Exception e) { this._messageService.ShowErrorMessage(e); }
}
}
public class SearchPresenter: PresenterBase
{
public SearchPresenter(IMessageService messageService)
: base(messageService)
{
}
public void Search()
{
this.ExecuteAction(() =>
{
//perform search action
});
}
}
Regarding your question about catching all exeptions. Unless you are doing something special for specific types of exceptions, I would suggest just handling all the same. The example I provided passes the exception to the message service so that the formatting specifics can be handled by your message service.
If you have not yet incorporated any sort of IoC container, you can always start by using the interface injection and then passing the instance explicitly from the child class constructor.
public class SearchPresenter: PresenterBase
{
public SearchPresenter()
: base(new SomeMessageService())
{
}
...
}
This is at least removes the static dependency and is not too dificult to swap out later if you ever introduce an IoC container.
I think your approach is good enough for your work. Wrapping logics by ExecuteAction is an acceptable way to me. As another option, I might use AOP for centralized exception handling in practice.
Also, I might use a MessagingService resolved from dependency injection container rather than a static one.
Regarding how to display the error, that's totally depend on your business purpose. For example, you could simply log the error and tell the user "something's wrong", or show them the complete stacktrace including the environment information so they could simply copy & paste in the email.
Lately I am working on exception logging module of a WCF service. Unfortunately the service hasn't been introduced with unit tests, therefore there are many unexpected exceptions occurring. And so far I have accomplished to get the exceptions with interceptor aproach, by implementing IErrorHandler interface and tying it to the service interface with IServiceBehaviour. I liked this functionality very much actually. But it brought me into a next step of desire of getting the details of exception. Like on which line did the exception occurred?
I can satisfy this desire by 2 ways in my mind:
By having a variable for keeping track of the lines I've passed through successfully, and including it in the exception thrown.
By catching exceptions from all lines seperately.
But both approaches seem very lousy to me. I am wondering is there a known design pattern or a tool to achive this goal?
In my opinion you might try using logging, such as log4net. Then you can find out where is and what happened. Exception object not always contains the stack info, because of "inlining", that occur during optimization etc.
include the PDB files for your service and the line numbers will be included in exception.ToString()
The way we have solved this problem is twofold:
Our services are dumb wrappers around commands. So when a service method is entered it delegates its work to a command.
We wrap every command call in a logging proxy that is responsible for logging input, output and errors and executing the command.
For example:
public FooServiceModel GetFoo(int fooId)
{
return new ILogged<GetFooCommand>().Target.Execute(fooId);
}
This delegates execution of the command to ILogged which:
Logs the command name
Logs the command parameters
Logs the execution result
Logs any exceptions
It also does some other stuff to link up the client request with the server call using custom message headers so that a call can be completely debugged from client to server and back. This is incredibly useful and allows us to diagnose even complex problems off site.
We use the Castle.Core dynamic proxy to implement ILogged with an interceptor that looks something like this (ILog is a log4net logger):
public class LoggingInterceptor : IInterceptor
{
public LoggingInterceptor([NotNull] object target, [NotNull] ILog logger)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (logger == null)
{
throw new ArgumentNullException("logger");
}
this.Target = target;
this.Logger = logger;
}
public object Target { get; set; }
public ILog Logger { get; set; }
public void Intercept(IInvocation invocation)
{
try
{
this.Logger.Debug(invocation);
invocation.ReturnValue = invocation.Method.Invoke(
this.Target, invocation.Arguments);
this.Logger.Debug("Invocation return value:");
this.Logger.Debug(invocation.ReturnValue);
}
catch (TargetInvocationException ex)
{
this.Logger.Error("Unable to execute invocation", ex);
if (ex.InnerException != null)
{
throw ex.InnerException;
}
throw;
}
}
}
The invocation itself is rendered by a custom log4net object renderer:
public class InvocationRenderer : IObjectRenderer
{
public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
{
var invocation = (IInvocation)obj;
var builder = new StringBuilder();
builder.AppendFormat(
"Invoking Method: {0} --> '{1}' with parameters (",
invocation.Method.DeclaringType != null
? invocation.Method.DeclaringType.FullName : "{Unknown Type}",
invocation.Method);
var parameters = invocation.Method
.GetParameters()
.Zip(invocation.Arguments, (p, a) => new { Parameter = p, Argument = a })
.ToArray();
var index = 0;
foreach (var parameter in parameters)
{
builder.AppendFormat(
"{0}: {1}",
parameter.Parameter.Name,
rendererMap.FindAndRender(parameter.Argument));
if (++index < parameters.Length)
{
builder.Append(", ");
}
}
builder.Append(")");
writer.Write(builder.ToString());
}
}
Hopefully that will give you some ideas on how to tackle this problem.