I am developing a distributed application. In it, there are roles and sets of permissions that I must validate.
Is a good pratice to throw an exception, in per example, unauthorized access?
Or should I send some message back to the client?
Using FaultExceptionFault exceptions are exceptions that are thrown by a WCF service when an exception occurs at runtime -- such exceptions are typically used to transmit untyped fault data to the service consumers.
. NET provides a very simple way of dealing with exceptions using try-catch-throw to provide a user an understandable message for a system generated exception. But a WCF service is consumed by some other application, not an end user.
On your service operation, you can specify a FaultContract that will serve both purposes like so:
[OperationContract] [FaultContract(typeof(MyServiceFault))] void MyServiceOperation();
Note that MyServiceFault must be marked with DataContract and DataMember attributes, in the same way you would a complex type:
[DataContract] public class MyServiceFault { private string _message; public MyServiceFault(string message) { _message = message; } [DataMember] public string Message { get { return _message; } set { _message = value; } } }
On the service-side, you are then able to:
throw new FaultException<MyServiceFault>(new MyServiceFault("Unauthorized Access"));
And on the client-side:
try { ... } catch (FaultException<MyServiceFault> fault) { // fault.Detail.Message contains "Unauthorized Access" }
Well, you can catch all exceptions in the WCF service implementations methods and rethrow them as FaultExceptions. By doing it this way, the exception will be rethrown on the client with a message of your choosing:
[OperationContract] public List<Customer> GetAllCustomers() { try { ... code to retrieve customers from datastore } catch (Exception ex) { // Log the exception including stacktrace _log.Error(ex.ToString()); // No stacktrace to client, just message... throw new FaultException(ex.Message); } }
To avoid having unexpected errors relayed back to the client, it's also a good practice to never throw Exception instances in code on the server-side. Instead create one or more of your own exception types and throw them. By doing so, you can distinguish between unexpected server processing errors and errors that are thrown due to invalid requests etc:
public List<Customer> GetAllCustomers() { try { ... code to retrieve customers from datastore } catch (MyBaseException ex) { // This is an error thrown in code, don't bother logging it but relay // the message to the client. throw new FaultException(ex.Message); } catch (Exception ex) { // This is an unexpected error, we need log details for debugging _log.Error(ex.ToString()); // and we don't want to reveal any details to the client throw new FaultException("Server processing error!"); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With