How to get business exception from wcf? - c#

How can I test for this exception as returned from a WCF call?
I have this error class.
[Serializable]
public class PermissionDenied_Error : Exception
{
public PermissionDenied_Error() : base("You are not approved.") { }
}
In my Service, I am throwing it.
if (notApproved)
{
throw new FaultException<PermissionDenied_Error>(new PermissionDenied_Error()
, new FaultReason("Permissions Denied!"));
}
In my test, I am expecting it.
[Test]
[ExpectedException(typeof(FaultException<PermissionDenied_Error>))]
Current result is:
Expected: System.ServiceModel.FaultException`1[[PermissionDenied_Error
, Project.API, Version=1.0.4318.24332, Culture=neutral, PublicKeyToken=null]]
but was: System.ServiceModel.FaultException : Permissions Denied!

Your PermissionDenied_Error should be a data contract. It should not be derived from Exception.
Also,you need to place the FaultContractAttribute on your operation contract so that the client knows to expect an exception.
Added by Valamas
public interface IAccess
{
[OperationContract]
[FaultContract(typeof(PermissionDenied_Error))]
DtoResponse Access(DtoRequest request);
}

in WCF simply does not work like that.
there are articles around explaining how to setup and use FaultExceptions
check this step by step here: Exception Handling in Windows Communication Framework and Best Practices

Using the ExpectedException attribute is a bad practice. Instead of using this:
[Test]
[ExpectedException(typeof(FaultException<PermissionDenied_Error>))]
try doing:
[Test]
public void Test1()
{
.....
try{
WfcServiceCall(...);
Assert.Fail("a FaultException<PermissionDenied_Error> was expected!");
}catch(FaultException<PermissionDenied_Error>){
Assert.Sucess();
}catch(Exception e){
Assert.Fail("Unexpected exception!")
}
}

Related

Cannot expose mongodb objectId through wcf to mvc

I'm facing an annoying problem while providing a wcf service. I am familiar with wcf and its usage.
Service Implementation:
public class Service : IService
{
public SampleClass SampleMethod ( SampleClass sampleParameter )
{
return new SampleClass { MyProperty1 = Guid.NewGuid(), MyProperty2 = ObjectId.GenerateNewId() };
}
}
Service interface:
[ServiceContract]
public interface IService
{
[OperationContract]
SampleClass SampleMethod ( SampleClass sampleParameter );
}
And my contract class:
/// this class is in DataContracts dll - meantioned in the exception
[DataContract]
public class SampleClass
{
[DataMember]
public Guid MyProperty1 { get; set; }
[DataMember]
public ObjectId MyProperty2 { get; set; }
}
I keep the interface and the contracts in seperate library projects and use the dlls at the clients.
MVC Side calling of service:
static IService Service = new ChannelFactory<IService>(new BasicHttpBinding("regularBinding"), new EndpointAddress(BaseAddress + "Service.svc")).CreateChannel();
public ActionResult Index()
{
var xyz = Service.SampleMethod(new SampleClass());
return View();
}
I can call this service from my unit test project or from a desktop application. But when I call the service from an MVC application it throws ProtocolException:
An exception of type 'System.ServiceModel.ProtocolException' occurred in mscorlib.dll but was not handled in user code
Additional information: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:sampleParameter. The InnerException message was 'Error in line 1 position 451. 'EndElement' 'MyProperty2' from namespace 'http://schemas.datacontract.org/2004/07/DataContracts' is not expected. Expecting element '_increment'.'. Please see InnerException for more details.
I have a hunch that this is caused by some serializer related issue, but I don't really have deep understanding on those topics, so here I am.
What might be the cause of this behaviour? How can I overcome this without changing my data structures?
Update
Btw I realized that the exception occurs on return. When I throw an exception from within the service method, that exception propogates to the client. Therefore I can say my request with ObjectId can be received from the service but cannot return to the client.
We've found out the problem and the solution in the discussion with #jpgrassi, but since #jpgrassi is too humble to post the answer, here I am.
Following the answer of this question #jeff's answer was inspiring enough to make me check the MongoDB.Bson dll's versions. There it was, they were different on server and mvc client and causing this problem. Leveling them on a version solved the problem.

Return Inherited Class into Base Class WCF Service

I am trying to return a derived class from the base class using WCF service, but I keep getting the following exception
"An error occurred while receiving the HTTP response to http://localhost:50137/Service.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server..."
I have tried adding all of the following over WCF Service method.
1) [XmlInclude(typeof(DerivedClass1)), XmlInclude(typeof(DerivedClass2))]
2) [SoapRpcMethod]
3) [SoapInclude(typeof(DerivedClass1)), SoapInclude(typeof(DerivedClass2))]
Code:
public class BaseClass
{
}
public class DerivedClass1:BaseClass
{
}
public class DerivedClass2:BaseClass
{
}
Wcf Service Method:
public BaseClass Validate()
{
if(someCondition)
return new DerivedClass1();
else
return new DerivedClass2();
}
[Serializable]
[DataContract]
[
KnownType(typeof(DerivedClass1)),
KnownType(typeof(DerivedClass2))
]
public class BaseClass
{
}
public class DerivedClass1:BaseClass
{
}
public class DerivedClass2:BaseClass
{
}
see
https://msdn.microsoft.com/en-us/magazine/gg598929.aspx for more information about Known Types and the Generic Resolver.
There are a number of problems with the code you've posted:
Your contract type and operation code have no ServiceModel annotations
You haven't specified how you're hosting the service
You haven't specified how you're calling the service
You haven't specified anything about the binding you're using
Until at least some of these are clarified I think the question is unanswerable. If you could edit your question to include these points I'll edit my answer.

ServiceStack - Error trying to resolve Service {X} or one of its autowired dependencies

I am using servicestack and having problems with auto wiring.
Error trying to resolve Service '{Service}' or one of its autowired dependencies (see inner exception for details)
I don't need help figuring how exactly what the problem is. What I actually want is a way to see the inner exception. The inner exception should tell me the except problem without me having to figure it out but it not displayed in either the exception returned, or in the logs.
Setting DebugMode doesn't help either, it just includes the stack track of the topmost exception.
So basically, how do I stop servicestack from hiding the inner exception details?
I ran into this same issue and it ended up being that there was an exception being thrown inside of the constructor that I had created for the particular endpoint class. Example...
public class PartnerService : Service
{
private PartnerManagementService _partnerManagementService;
public PartnerService()
{
var configuration = new Configuration();
_partnerManagementService = new PartnerManagementService(configuration);
}
public object Get(PartnerGet partner)
{
try
{
var partners = _partnerManagementService.getPartners();
if (!partners.Any())
{
return new HttpError(HttpStatusCode.NotFound, "Partners Could not be found");
}
return partners;
}
catch (Exception e)
{
return new HttpError(HttpStatusCode.InternalServerError, e);
}
}
If it so happens that an exception is thrown inside of the constructor, ServiceStack will not be able to resolve the service or one of its dependencies, in this case that dependency being the constructor for the class.
If you put a try/catch in the constructor for the class you could get an exception that actually makes sense.
ServiceStack should already return the inner Exception, i.e. here's the source of the error:
private Exception CreateResolveException<TService>(Exception ex)
{
var errMsg = "Error trying to resolve Service '{0}' or one of its autowired dependencies (see inner exception for details).".Fmt(typeof(TService).FullName);
return new Exception(errMsg, ex);
}
Basically there was a problem with your IOC configuration and that one of the dependencies caused an error.
You can change ServiceStack to serialize the Inner Exception with:
SetConfig(new EndpointHostConfig {
ReturnsInnerException = true,
});
But this already defaults to true.
So the exception should already contain the Inner Exception, are you referring to what Exception gets serialized or the exception thrown in code?
One option could be to grab the actual source code from Github and add it as a project to your solution, as opposed to using a compiled DLL, then you could step through the actual code and see exactly where the exception is raised and why.
I have exactly the same exception.
In my case, it happens once migrated to ServiceStack v4. With v3, all works perfectly.
IoC configuration
public class AppHost : AppHostBase
{
public AppHost() : base("Northwind web services", typeof(CustomersService).Assembly)
{ }
public override void Configure( Container container )
{
SetConfig(new HostConfig
{
DebugMode = true,
ReturnsInnerException = true,
});
var dbFactory = new OrmLiteConnectionFactory("~/Northwind.sqlite".MapHostAbsolutePath(), SqliteDialect.Provider);
container.Register(dbFactory);
// Dependencies
container.RegisterAs<CustomerEntityRepository, ICustomerEntityRepository>();
container.RegisterAutoWired<CustomersService>();
}
}
Base class
public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : IEntity, new()
{
protected IDbConnectionFactory dbFactory { get; set; }
public Repository( IDbConnectionFactory factory )
{
dbFactory = factory;
}
}
Inherited class
public class CustomerEntityRepository : Repository<CustomerEntity>, ICustomerEntityRepository
{
public CustomerEntityRepository( IDbConnectionFactory dbFactory )
: base(dbFactory)
{
}
}
}
Only solution I've found is:
container.RegisterAs<ICustomerEntityRepository>(c => new CustomerEntityRepository(dbFactury));
Here's full exception message returned http://pastebin.com/jJntNN5p

[ExpectedException(typeof(AnExceptionBaseException))]

I wrote a unit test in such a way that it should throw AnException or AnotherException, both deriving from AnExceptionBaseException. I then proceeded to add an ExpectedExceptionAttribute for the base exception, only to find that my test will still be marked as failed.
Test Name: Call_Should_Throw_If_Device_Is_Not_Ready Test
...
Result Message: Test method
DiskManagementTests.DiskFreeSpaceTests.Call_Should_Throw_If_Device_Is_Not_Ready
threw exception System.IO.FileNotFoundException, but exception
System.IO.IOException was expected. Exception message:
System.IO.FileNotFoundException: The device is not ready. (Exception
from HRESULT: 0x80070015)
This seems like a reasonable design decision because, in this particular case, the exception is generated from an HRESULT return code. That makes it nearly impossible to determine which exception will be thrown. At least not without copying the code logic from the unit that my test is supposed to ...test.
My code (I believe this can throw either FileNotFound or DirectoryNotFound):
[TestMethod]
[ExpectedException(typeof(IOException))]
public void Call_Should_Throw_If_Device_Is_Not_Ready()
{
foreach (DriveInfo drive in DriveInfo.GetDrives().Where(drive => !drive.IsReady))
{
DiskFreeSpace diskFreeSpace = DiskManagement.GetDiskFreeSpace(drive.RootDirectory.FullName);
Assert.Fail("API call did not fail even though the drive reports that it is not ready.");
}
Assert.Inconclusive("All drives were ready. Try testing with an empty disc drive.");
}
Do I need to reconsider the way I write unit tests?
EDIT
This scenario is supported after all. All it really took was setting AllowDerivedTypes to true.
[TestMethod]
[ExpectedException(typeof(IOException), AllowDerivedTypes = true)]
public void Call_Should_Throw_If_Device_Is_Not_Ready()
{
// ...
}
You can create your own ExpectedException attribute that will check if the thrown exception inherites the Exception defined in the attribute.
public sealed class MyExpectedException : ExpectedExceptionBaseAttribute
{
private Type _expectedExceptionBaseType;
public MyExpectedException(Type expectedExceptionType)
{
_expectedExceptionBaseType = expectedExceptionType;
}
protected override void Verify(Exception exception)
{
Assert.IsNotNull(exception);
Assert.IsTrue(exception.GetType().IsInstanceOfType(typeof(_expectedExceptionBaseType)) ||
exception.GetType().IsSubclassOf(typeof(_expectedExceptionBaseType)));
}
}
and change the attribute to your test:
[MyExpectedException(typeof(IOException))]

What is the right time to throw an exception in an API?

I'm building a API for my pet software and I'm in the following situation:
A service that use another service. I have a service that use another service for load a Assembly, should I throw a exception in the service that load a assembly or on the service that use that service?
AssemblyService:
public class AssemblyService : IAssemblyService
{
public Assembly Load(string assemblyName)
{
Assembly assembly;
try
{
assembly = Assembly.Load(assemblyName);
}
catch
{
assembly = null;
}
return assembly;
}
...
}
Service that use AssemblyService:
public class CommandService : ICommandService
{
private readonly IAssemblyService assemblyService;
public CommandService(IAssemblyService assemblyService)
{
this.assemblyService = assemblyService;
}
public CommandOutput Process(string inputCommand, string requestInfo)
{
string commandName = GetAssemblyName(inputCommand);
string args = GetArgs(inputCommand);
Assembly assembly = assemblyService.Load(commandName);
if (assembly == null) throw new UnknownCommandException(commandName);
ICommand command = assemblyService.GetCommand(assembly);
return command.Execute(args, requestInfo);
}
#region Private methods
...
#endregion
}
Should I throw the exception in AssemblyService or CommandService like the above example?
I'm trying to learn how to handle a exception, in the above example the line assembly = Assembly.Load(assemblyName); can throw ArgumentNullException, ArgumentException, FileNotFoundException, FileLoadException and BadImageFormatException. Should I handle all these exceptions?
UnknownCommandException(commandName) is a custom exception.
Other question: Anyone who's using my API could know when a method could throw a exception? I see placing the mouse over any methods of .Net Framework you will see if the method could throw a exception. Could this works with methods of my API?
Your title is about throwing exceptions but you actually seem to be talking about catching exceptions. You should generally not catch exceptions unless you can do something meaningful to rectify the condition that caused the exception to be thrown in the first place, and in that case you should only catch the explicit exception types that you can handle.
There are two things to think about here:
Will the normal flow of the application be abruptly halted to the point where it will no longer work? Exceptions are exactly that - a notification that something exceptional (out of the ordinary, abnormal, etc.) has happened. If it isn't exceptional, don't throw an exception. If the user can continue to use the program without noticing, don't use an exception.
How you comment the method declaration will affect this. There should be some markup tags for the comments that will allow you to explain what exception will be thrown and under what circumstances it will be thrown. They look like this:
/// <exception cref="ExceptionTypeGoesHere"></exception>
I normally try and avoid using exceptions to control the flow of the program. Your program uses an exception to convert it to a result variable and then converts that back to an exception. Why not stick with exceptions all the way? I would change it as follows:
public class AssemblyService : IAssemblyService
{
public Assembly Load(string assemblyName)
{
return Assembly.Load(assemblyName);
}
}
public class CommandService : ICommandService
{
private readonly IAssemblyService assemblyService;
public CommandService(IAssemblyService assemblyService)
{
this.assemblyService = assemblyService;
}
public CommandOutput Process(string inputCommand, string requestInfo)
{
string commandName = GetAssemblyName(inputCommand);
try
{
string args = GetArgs(inputCommand);
Assembly assembly = assemblyService.Load(commandName);
ICommand command = assemblyService.GetCommand(assembly);
return command.Execute(args, requestInfo);
}
catch (Exception ex)
{
//Log original exception or add to inner exception
throw new UnknownCommandException(commandName);
}
}
}
api as the name suggests is the gateway to an application. if an error occurs in the api, it is most useful for the api to tell the consumer why, where and when the error happened i.e. api throws the exception out. it is up to the consumer to catch this and tell its users what to do or if the business logic is defined well the consumer will calculate alternative execution paths. this is my rule of thumb
in the example above the assembly load service should throw the error out. If you handle this in the api, then the consumer will never learn :)
for general guidelines to exception handling look here in Msdn

Categories