I am trying to send an exception over the WCF wire but can't figure out what I have done wrong.
I am following the guidance of Oleg Sych and MSDN but to no avail.
What I get back is The requested service, 'net.tcp://mymachine/myservicepath/MyService.svc' could not be activated. See the server's diagnostic trace logs for more information..
[ServiceContract]
public interface ISystemInfoService
{
[OperationContract]
[FaultContract(typeof(MyException))]
void DoThrowException(string message);
}
//[ServiceContract] // <- the culprit
public class SystemInfoService : ISystemInfoService
{
public void DoThrowException(string message)
{
try
{
throw new MyException( "MyMessage" );
}
catch (MyExceptionexc)
{
throw new FaultException<MyException>(exc);
}
}
}
// The custom Exception resides in an common assembly reachable from both server and client.
[Serializable]
public class MyException: Exception
{
...
}
TIA
Can you try handling the exception with a datacontract class instead of serializable exception?
[DataContract]
public class MyExceptionClass
{
[DataMember]
public Exception Exc { get; set; }
}
[ServiceContract]
public interface ISystemInfoService
{
[OperationContract]
[FaultContract(typeof(MyExceptionClass))]
void DoThrowException(string message);
}
public class SystemInfoService : ISystemInfoService
{
public void DoThrowException(string message)
{
try
{
throw new Exception("MyMessage");
}
catch (Exception exc)
{
var data = new MyExceptionClass { Exc = exc };
throw new FaultException<MyExceptionClass>(data);
}
}
}
Related
I'm having quite a bit of difficulty in getting a custom exception message to return from my Web Api solution. It's a bit more complicated than that:
I want to override the read only property of the exception with my own:
public class CustomException : Exception
{
public CustomException(string message)
: base(message)
{
}
public CustomException(string message, Exception inner)
: base(message, inner)
{
}
}
However, I also have a global exception handler:
public class GlobalExceptionLogger : ExceptionLogger
{
public override void Log(ExceptionLoggerContext context)
{
if (context.Exception.Message == "Password has already been used in the past...1")
{
throw new CustomException("some msg", context.Exception);
}
NLogger.LogError("Global Error Handler", context.Exception);
}
}
When I throw the error I do so like:
if (some condition)) throw new CustomException("some msg");
And then I catch it in the method like:
catch (CustomException ex)
{
throw ex;
}
catch (Exception ex)
{
NLogger.LogError(ex);
throw;
}
How can I set the message to be "some msg"? What I'm trying to do is have the api return 1-2 use case related error messages with customErrors mode set to on.
throw new HttpResponseException(
new HttpResponseMessage
{
StatusCode = code,
ReasonPhrase = phrase,
Content = new StringContent(body)
});
I have a global try/catch around my application methods to log unhandled exceptions and show an error message. For logging I use NLog. If I handle an exception and log it manually I set a key 'logged' in the exceptions data object to prevent the second log from the global try/catch.
public partial class App : Application
{
public static void Main(string[] args)
{
try
{
// Application stuff
SomeMethod();
}
catch (Exception ex)
{
if (ex.Data['logged'] == false)
{
logger.Error(ex, "A unhandled exception occured.")
ex.Data['logged'] = true;
}
// Show error dialog
}
}
public static void SomeMethod()
{
try
{
// Method stuff
}
catch (Exception ex)
{
logger.Error(ex, "A handled exception occured.")
ex.Data['logged'] = true;
throw;
}
}
}
I want to simplify the process so that I don't have to call ex.Data['logged'] = true; manually. Is there a way to modify the data property of an exception automatically while logging with NLog? I tried to use a MethodCall-Target but I had no access to the exception reference. The exception could only be passed as a string.
Would it work for you to use NLog to perhaps modify your approach to logging exceptions slightly?
public partial class App
{
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
public static void Main(string[] args)
{
try
{
SomeMethod();
}
catch (Exception ex)
{
logger.ErrorEx(ex, "message");
}
}
public static void SomeMethod()
{
try
{
// Method stuff
}
catch (Exception ex)
{
logger.ErrorEx(ex, "A handled exception occured.");
throw;
}
}
}
public static class NLogExt
{
public static void ErrorEx(this NLog.Logger logger, Exception ex, string message)
{
if (ex.Data["logged"] as bool? == true) return;
logger.Error(ex, message);
ex.Data.Add("logged", true);
}
}
I have to make my own Exception Class for .NET project. Could somebody please help how can I use it in the code? I just to show to MessageBox to user that the images were not found. But I don't know where to do it. Hoping for a good answer.
class RijException : Exception
{
public RijException()
: base() { }
public RijException(string message)
: base(message) { }
public RijException(string format, params object[] args)
: base(string.Format(format, args)) { }
public RijException(string message, Exception innerException)
: base(message, innerException) { }
public RijException(string format, Exception innerException, params object[] args)
: base(string.Format(format, args), innerException) { }
}
Now I want to use it:
try
{
afbeeldingPictureBox.BackgroundImage =
Image.FromFile(#"..\..\Borden\Stilstaan en parkeren\Parkeren toegelaten.png");
}
catch (FileNotFoundException)
{
throw new RijException("Can't find the images");
}
Edit
try
{
try
{
afbeeldingPictureBox.BackgroundImage = Image.FromFile(#"..\..\Borden\Stilstaan en parkeren\Parkeren toegelaten.png");
}
catch (FileNotFoundException)
{
throw new RijException("ImageNotFound");
//MessageBox.Show("Afbeeldingen konden niet worden geladen");
}
}
catch (RijException)
{
MessageBox.Show("Not able to load the image...");
}
Your example could be improved, but before that let's take a more useful example.
Imagine that you have the following code:
class Program
{
static void Main(string[] args)
{
try
{
var processor = new FileProcessor();
processor.Run();
}
catch (RijException exception)
{
//what will I get here.
}
}
}
Which uses the following classes:
public class FileProcessor
{
private string _myFileName;
public void Run()
{
try
{
var fileLoader = new FileLoader();
Process(fileLoader.Load(_myFileName));
}
catch (FileNotFoundException)
{
throw new RijException("Can't find requested file");
}
}
private void Process(object file)
{
//some logic
}
}
public class FileLoader
{
public object Load(string myFileName)
{
//throws FileNotFoundException
}
}
So the call stack will be like this:
If we modify the code in the main method to print the stack trace, what do you think that we get?
try
{
var processor = new FileProcessor();
processor.Run();
}
catch (RijException exception)
{
Console.WriteLine(exception.StackTrace);
}
The correct answer is:
See? The stack trace shows that the error happened in FileProcessor while it really happened in FileLoader. The reason to that is this code:
catch (FileNotFoundException)
{
throw new RijException("Can't find requested file");
}
When you catch an exception and throw another one you must always include the original exception as the inner exception. Otherwise it will be hard to understand where the exception originally occurred.
catch (FileNotFoundException ex)
{
throw new RijException("Can't find requested file", ex); //includes inner
}
Another problem is the exception message: "Can't find requested file". Ask yourself. If you get that message in a log file, would you be able to figure out what went wrong? At least give some context information.
Finally you have another problem. Best practices for designing exceptions says that they should be able to get serialized. To do that you need to include the serialization constructor and mark the exception as serializable:
[Serializable]
public class RijException : Exception
{
public RijException(string message) : base(message)
{
}
public RijException(string message, Exception inner) : base(message, inner)
{
}
//serialization constructor
protected RijException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
}
Finally I would therefore write your exercise like this:
try
{
var filename = #"..\..\Borden\Stilstaan en parkeren\Parkeren toegelaten.png";
try
{
afbeeldingPictureBox.BackgroundImage = Image.FromFile(filename);
}
catch (FileNotFoundException exception)
{
throw new RijException("Failed to load " + filename, exception);
}
}
catch (RijException)
{
MessageBox.Show("Not able to load the image...");
//now you would have all information required
//to figure out where and why something went wrong.
}
Summary
Always include inner exceptions
Provide useful context information so that you can figure out what went wrong
Make sure that exceptions can be serialized.
It is generally not a great idea to catch an exception that you cannot do much about. Just catching the FileNotFoundException and then throwing a new RijException that essentially conveys the same information is not usually done.
I just to show to MessageBox to user that the images were not found. But I don't know where to do it.
The most direct way to restructure your code to show the message box is
catch (FileNotFoundException)
{
MessageBox.Show("Can't find the images.");
//Don't do this: throw new RijException("Can't find the images");
}
You really do not want your custom RijException to take on the responsibility of displaying the MessageBox.
public void DoRiskyThings(List<Action> tasks)
{
List<Exception> exceptions = new List<Exception>();
foreach(Action task in tasks)
{
try {task()}
catch (Exception e) {exceptions.Add(e)};
}
if (exceptions.Any())
{
//... what goes here?
}
}
I'd like to preserve all the information (especially messages and stacktraces).
You're looking for the AggregateException class.
Just bundle your list into a super-exception:
class MultiException : Exception
{
public List<Exception> ExceptionsList { get; set; }
}
I have a Ria service to call logic code. I want to write try catch block in every logic function to provide ways to handle unhandeled exceptions.
try
{
//something
}
catch(BussinessException e)
{
//save e.info to database
}
But I don't want to write this block code everywhere in my logic, and I don't want to put the exception handling piece in RIA service since another type of service also call the logic.
Does anybody have a one-place exception handling solution for me?
Based off your history I am pretty sure this is C# so here is my take.
The best way to avoid the duplication would be to wrap your logic like this.
private static void ExecuteLogic(Action action)
{
try
{
action();
}
catch(BussinessException e)
{
//save e.info to database
}
}
With this in place you can easily perform various operations that share the same error handling.
ExecuteLogic(
() =>
{
// Do something...
}
);
If you want only to log exception, as I can see from your example, you can subscribe to AppDomain.FirstChanceException. But you wouldn't be able to handle it. Oh. btw this event was introduces only in .NET 4 :(.
Here is a more conventional Object Oriented solution using Command Pattern.
public interface ICommand {
void Execute();
}
public class BankAccountWebServiceCall: ICommand(){
string name;
int accountNo;
public BankAccountWebServiceCall(string name, int accountNo) {
this.name= param1;
this.accountNo= accountNo;
}
//ICommand implementation
public void Execute() {
SomeWebService.Call(name, accountNo);
}
}
public class WebServiceCaller {
public void CallService(ICommand command) {
try {
command.Execute();
} catch (SomeBusinessException ex) {
//handle exception
}
}
}
public class WebServiceCallerTest {
public static void CallServiceTest() {
new WebServerCaller().CallService(new TwoParameterwebServiceCall("Igor", 12345));
}
}
implement an IHttpModule
web.config:
<httpModules>
...
<add type="Citiport.Web.Module.ErrorHandleModule" name="GlobalErrorHandler" />
...
</httpModules>
The Class:
public class ErrorHandleModule : IHttpModule
{
private static readonly ILog logger = LogManager.GetLogger("Citiport.Web.Module.ErrorHandleModule");
public ErrorHandleModule()
{
}
void IHttpModule.Dispose()
{
}
void IHttpModule.Init(HttpApplication context)
{
context.Error += new System.EventHandler(onError);
}
public void onError(object obj, EventArgs args)
{
HttpContext ctx = HttpContext.Current;
HttpResponse response = ctx.Response;
HttpRequest request = ctx.Request;
Exception exception = ctx.Server.GetLastError();
/* handling exception here*/
}
}
}
refer:http://code.google.com/p/citiport2/source/browse/trunk/CitiportV2_website/App_Code/Web/ErrorHandleModule.cs