How can I set return to accept class1 or class2?

how can I, in my function, start filling in the parameters for the class that it should return, but if an exception occurs, will I return my error class instead?

public **** function() { try { Articles articles = new Articles(); articles.articleid = 234; articles.articlename = "Milk"; articles.deleted = 0; //continue fill Articles //and an exception occurs return articles; } catch (Exception e) { Errors Error = new Errors(); Error.exceptionmessage = e.Message; Error.exceptionname = e.ToString(); Error.httpcode = 500; return Error; } } 

Is it possible and good? or should I just extend all return classes with my error class, although I will return a lot of information with highlighted null values. I would like to send as little data as possible, and if my function failed, I will just send an error back.

UPDATE

sorry for not giving enough information about my situation, this is the function I want to use in webservice

 [OperationContract] [WebGet( ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] **** Function(); 

so I don’t think I can just throw an exception. I would like to return the article class if everything is fine, so I do not need to convert my data to JSON, but if something goes wrong, I would like to send the 500 Internal Server Error HTTP code to the client. I haven’t read all the answers yet, but I think I will have to include my error class in all my other return classes so that the client can now when something goes wrong?

+4
source share
7 answers

I would honestly advise you to do what you offer. Instead, either use the existing Exception type, or create a new subclass of Exception and throw it away. You can even store information about the calling exception in the new InnerException if necessary.


If the situation does not guarantee an exception, however (you did not provide enough details about what you are doing), you can create a Result class containing error / warning information. However, such things are better suited for warnings. That is, this is not an error condition that prevents the continuation of events (exception), but instead a message that the calling code can ignore without sharp side effects.

For instance:

 class Result<T> { public Result(T Value, Errors Errors = null) { this.Value = Value; this.Errors = Errors; } public T Value {get; private set;} public Errors Errors {get; private set;} } 

Usage (as per your code example):

 public Result<Articles> function() { try { Articles articles = new Articles(); articles.articleid = 234; articles.articlename = "Milk"; articles.deleted = 0; //continue fill Articles //and an exception occurs return new Result(articles); } catch (Exception e) { Errors Error = new Errors(); Error.exceptionmessage = e.Message; Error.exceptionname = e.ToString(); Error.httpcode = 500; return new Result<Articles>(null, Error); } } 
+8
source

UPDATE:

This gives more information about what you want to do. Since you cannot throw exceptions, you must have a base class of results. I usually do this for WCF methods, which I call through javascript, since it cannot handle exceptions nicely.

So you need a base class, for example:

 [DataContract] public class AjaxResult { public static AjaxResult GetSuccessResult() { return new AjaxResult(); } [DataMember] public int Status { get; set; } [DataMember] public string Error { get; set; } } 

You can then inherit this by adding any data you want to return. This example returns a single product object and a list of validation errors.

 [DataContract] public class SingleProductResult : AjaxResult { [DataMember] public Product Data { get; set; } [DataMember] public IList<int> ValidationErrors { get; set; } } 

You can also create a universal wrapper so you don't have to write a lot of code in your methods. I usually put this in a base class and let all WCF services inherit from this class.

 protected T PerformAjaxOperation<T>(Func<T> action) where T : AjaxResult, new() { try { return action(); } catch (AccessDeniedException ade) { // -- user tried to perform an invalid action return new T() { Status = AjaxErrorCodes.AccessDenied, Error = ade.ToString() }; } catch (Exception ex) { return new T() { Error = ex.ToString(), Status = 1 }; } } 

Then just use it like this:

 public SingleProductResult GetProduct(int productId) { return PerformAjaxOperation(() => { return retval = new SingleProductResult() { Data = ProductServiceInstance.GetProduct(productId) }; }); } public AjaxResult DeleteProduct(int productId) { return PerformAjaxOperation(() => { ProductServiceInstance.DeleteProduct(productId); return AjaxResult.GetSuccessResult(); }); } 

So, if everything went smoothly, the error will be 0, and the message will be zero. If an exception is thrown, it will be caught by the PerformAjaxOperation() function and populated inside the AjaxResult object (or its derivative) and return to the client.


Previous answer:

I do not think it's a good idea. You can create a custom exception by creating a class that inherits from Exception and add the properties you want to keep there. Then, when an exception occurs, you simply catch it and fill it inside this new exception along with other details. Then throw this exception. Then you can catch this exception at higher levels and display the correct message.

example:

 public IList<Articles> GetArticles() { try { return GetSomeArticlesFromDatabase(); } catch (Exception innerException) { throw new MyCustomException("some data", 500, innerException); } } public class MyCustomException : Exception { public int HttpCode { get; set; } public MyCustomException(string errorMessage, int httpCode, Exception innerException) : base(errorMessage, innerException) { HttpCode = httpCode; } } public void EntryPoint() { try { DoSomething(); var result = GetArticles(); DoSomething(); DisplayResult(result); } catch (MyCustomException ex) { ReturnHttpError(ex.Message, ex.HttpCode); } } 
+10
source

If class1 and class2 have a common base type or common interface, use this. But in this case, you can create a wrapper class to encapsulate both types of results, for example:

 class MethodResult<T> { public T Result { get; private set; } public Errors Errors { get; private set; } public MethodResult(T result) { this.Result = result; } public MethodResult(Errors errors) { this.Errors = errors; } } public MethodResult<Articles> MyMethod() { try { ... return new MethodResult<Articles>(articles); } catch(Exception e) { ... return new MethodResult<Articles>(errors); } } 
+1
source

In light of the additional information in the question, since this is a WCF service, you can throw a WebFaultException :

 public Articles function() { try { Articles articles = new Articles(); articles.articleid = 234; articles.articlename = "Milk"; articles.deleted = 0; //continue fill Articles //and an exception occurs return articles; } catch (Exception e) { throw new WebFaultException(System.Net.HttpStatusCode.InternalServerError) { Message = e.Message }; } } 
+1
source

You can try out keyword

 public Articles function(out Error err) { Articles articles = null; err = null; try { articles = new Articles(); articles.articleid = 234; articles.articlename = "Milk"; articles.deleted = 0; // Set your article values } catch (Exception e) { Errors ex = new Errors(); ex.exceptionmessage = e.Message; ex.exceptionname = e.ToString(); ex.httpcode = 500; err = ex; } return articles; } 
0
source

Ways to solve other issues include technical methods for defining two classes using interfaces and subclasses.

However, in principle, you are really solving the wrong problem. You still have to write code in the caller, which distinguishes between two types of objects, and also documents how your function works.

Personally, I would create a new Exception class for the type of error you can handle, and throw this instead, for example:

 public class InvalidArticleException: Exception { public string ExceptionMessage { get; set; } public string ExceptionName { get; set; } public int HttpCode { get; set; } } public **** function() { try { // DO STUFF return articles; } catch (InvalidArgumentException e) { throw new InvalidArticleException() { ExceptionMessage = e.Message, ExceptionName = e.ToString(), HttpCode = 500 } } catch (Exception ex) { // Not actually required; left in for future debugging throw ex; } } 

Then, callers will be able to catch the exception and examine it for error details, and the code that is stored separately from the one that processes the returned articles

0
source

I'm not sure why you want to catch exceptions, but if you do, then this mode will make the return type common to both types. Both classes inherit an object, so you can change the method signature to public object function()

-one
source

Source: https://habr.com/ru/post/1491806/


All Articles