I have this code below, about a class responsible for handle exceptions and log them.
using ProReserve.Reserve.Domain.Licenciados;
using ProReserve.Reserve.Domain.Sistema.Logging;
using ProReserve.Reserve.Domain.Usuarios;
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Controllers;
namespace ProReserve.Reserve.API.Filters
{
public class DefaultControllerActionInvoker : ApiControllerActionInvoker
{
private Func<HttpRequestMessage, ILoggingService> _getLoggingService;
public DefaultControllerActionInvoker(Func<HttpRequestMessage, ILoggingService> getLoggingService)
{
_getLoggingService = getLoggingService;
}
public override async Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
Task<HttpResponseMessage> actionTask = base.InvokeActionAsync(actionContext, cancellationToken); // (*)
if (actionTask.Exception != null &&
actionTask.Exception.GetBaseException() != null &&
actionContext.Request.Properties["Licenciado"] as Licenciado != null)
{
var exception = actionTask.Exception.GetBaseException();
Operacao operacao = this.getHttpStatusCode(actionTask.Result);
await SaveLogAsync(exception, actionContext.Request, operacao);
return await Task.Run(() => new HttpResponseMessage(actionTask.Result.StatusCode)
{
Content = new StringContent(exception.Message),
ReasonPhrase = "Error"
});
}
return await actionTask;
}
private async Task SaveLogAsync(Exception exception, HttpRequestMessage request, Operacao operacao)
{
var guidLog = string.Format("{0}{1}", DateTime.Now.Ticks, Thread.CurrentThread.ManagedThreadId);
var requestInfo = string.Format("{0} {1}", request.Method, request.RequestUri);
var httpContext = request.Properties["MS_HttpContext"] as HttpContextBase;
var remoteAddr = httpContext.Request.ServerVariables["REMOTE_ADDR"];
var serverName = httpContext.Request.ServerVariables["SERVER_NAME"];
var logonUser = httpContext.Request.ServerVariables["LOGON_USER"];
var usuario = request.Properties["Usuario"] as Usuario;
var message = string.Format("{0} {1}", exception.Message.ToString(), exception.InnerException != null ? exception.InnerException.ToString() : string.Empty);
var logEntry = new Log(guidLog, operacao)
{
IDUsuario = usuario.ID,
IPCliente = remoteAddr,
IPServidor = serverName,
MaquinaCliente = logonUser,
Mensagem = string.Format(#"RequestInfo: {0} - Error: {1}", requestInfo, message),
};
using (var loggingService = _getLoggingService.Invoke(request))
{
loggingService.Licenciado = (Licenciado)request.Properties["Licenciado"];
await Task.Run(() => loggingService.Inserir(logEntry));
}
}
private Operacao getHttpStatusCode(HttpResponseMessage response)
{
Operacao operacao = Operacao.Response;
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
switch (response.StatusCode)
{
case System.Net.HttpStatusCode.BadRequest: //400
operacao = Operacao.BadGateway;
break;
case System.Net.HttpStatusCode.Unauthorized: //401
operacao = Operacao.Unauthorized;
break;
case System.Net.HttpStatusCode.PaymentRequired: //402
operacao = Operacao.PaymentRequired;
break;
case System.Net.HttpStatusCode.Forbidden: //403
operacao = Operacao.Forbidden;
break;
case System.Net.HttpStatusCode.NotFound: //404
operacao = Operacao.NotFound;
break;
case System.Net.HttpStatusCode.MethodNotAllowed: //405
operacao = Operacao.MethodNotAllowed;
break;
case System.Net.HttpStatusCode.NotAcceptable: //406
operacao = Operacao.NotAcceptable;
break;
case System.Net.HttpStatusCode.ProxyAuthenticationRequired: //407
operacao = Operacao.ProxyAuthenticationRequired;
break;
case System.Net.HttpStatusCode.RequestTimeout: //408
operacao = Operacao.RequestTimeout;
break;
case System.Net.HttpStatusCode.Conflict: //409
operacao = Operacao.Conflict;
break;
case System.Net.HttpStatusCode.Gone: //410
operacao = Operacao.Gone;
break;
case System.Net.HttpStatusCode.LengthRequired: //411
operacao = Operacao.LengthRequired;
break;
case System.Net.HttpStatusCode.PreconditionFailed: //412
operacao = Operacao.PreconditionFailed;
break;
case System.Net.HttpStatusCode.RequestEntityTooLarge: //413
operacao = Operacao.RequestEntityTooLarge;
break;
case System.Net.HttpStatusCode.RequestUriTooLong: //414
operacao = Operacao.RequestUriTooLong;
break;
case System.Net.HttpStatusCode.UnsupportedMediaType: //415
operacao = Operacao.UnsupportedMediaType;
break;
case System.Net.HttpStatusCode.RequestedRangeNotSatisfiable: //416
operacao = Operacao.RequestedRangeNotSatisfiable;
break;
case System.Net.HttpStatusCode.ExpectationFailed: //417
operacao = Operacao.ExpectationFailed;
break;
case System.Net.HttpStatusCode.InternalServerError: //500
operacao = Operacao.InternalServerError;
break;
case System.Net.HttpStatusCode.NotImplemented: //501
operacao = Operacao.NotImplemented;
break;
case System.Net.HttpStatusCode.BadGateway: //502
operacao = Operacao.BadGateway;
break;
case System.Net.HttpStatusCode.ServiceUnavailable: //503
operacao = Operacao.ServiceUnavailable;
break;
case System.Net.HttpStatusCode.GatewayTimeout: //504
operacao = Operacao.GatewayTimeout;
break;
case System.Net.HttpStatusCode.HttpVersionNotSupported: //505
operacao = Operacao.HttpVersionNotSupported;
break;
default:
operacao = Operacao.Response; //51
break;
}
}
return operacao;
}
}
}
In the line (*) - Task<HttpResponseMessage> actionTask = base.InvokeActionAsync(actionContext, cancellationToken);) - I have a command that intercepts an action async invoke. The variable actionTask returns with some properties. I need two of those properties filled, not null. They are:
Result -> get the StatusCode returned
Exception -> get the exception returned
I need both of those properties loaded, but I can't do a unit test where both of them are not null. In some test, Result comes not null, and other test, Exception comes not null, but never both of them.
Below is my unit test:
[TestMethod]
public void ActionAsync_Com_Exception()
{
// Arrange
Log log = null;
_loggingService.SetupSet(l => l.Licenciado = _licenciado);
_loggingService.Setup(a => a.Inserir(It.IsAny<Log>()))
.Callback<Log>((l) =>
{
log = l;
});
//Task<object> task1 = Task<object>.Factory.StartNew(() => new Exception()); //(3)
Task<object> task1 = Task<object>.Factory.StartNew(() =>
{
object myClass = new object();
return myClass;
});
//_actionDescriptor.Setup(a => a.ExecuteAsync(It.IsAny<HttpControllerContext>(), It.IsAny<IDictionary<string, object>>(), It.IsAny<CancellationToken>()))
// .Throws(new Exception("exception")); //(1)
_actionDescriptor.Setup(a => a.ExecuteAsync(It.IsAny<HttpControllerContext>(), It.IsAny<IDictionary<string, object>>(), It.IsAny<CancellationToken>()))
.Returns(task1); //(2)
DefaultControllerActionInvoker actionInvoker = new DefaultControllerActionInvoker(r => _loggingService.Object);
// Act
HttpResponseMessage response = actionInvoker.InvokeActionAsync(_baseActionContext, CancellationToken.None).Result;
// Assert
Assert.AreEqual(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.AreEqual("Error", response.ReasonPhrase);
Assert.AreEqual("127.0.0.1", log.IPCliente);
Assert.AreEqual("0.0.0.0", log.IPServidor);
Assert.AreEqual("USER\\MACHINE", log.MaquinaCliente);
Assert.AreEqual("RequestInfo: POST http://localhost/teste - Error: exception ", log.Mensagem);
_loggingService.VerifySet(l => l.Licenciado = _licenciado);
_loggingService.Verify(a => a.Inserir(It.IsAny<Log>()));
_loggingService.Verify(a => a.Dispose());
}
In my test I have tried:
(1) In this case, it returns an exception, but Result property comes null.
(2) In this case, it returns a result, but Exception property comes null. In this case, I need also to mock some way, to return some error statuscode (40x or 50x). But I donĀ“t know what to do.
(3) I have already tried creating a task which fires an exception, but gets into the case (2) above
So, I can't make my unit test works as well.
What do I need to do in my unit test code to get those two properties loaded?
Not sure I'm following what's going on in your code, but the bottom line is that you have asynchronous completion going on, for which your test assertions are not waiting. It means that the assertions are executing while or perhaps before the asynchronous code executes, so they don't test the results.
The standard test framework doesn't adequately support async/await, so if you're calling a method returning something of Task, you have to wait on the task - essentially make your test code synchronous... given what you've done, I think one extra line may do the trick:
// Act
HttpResponseMessage response = actionInvoker.InvokeActionAsync(_baseActionContext, CancellationToken.None).Result;
// After you have obtained the returned Task object,
// and done whatever will initiate the asynchronous activity, wait for it to complete...
task1.Wait(); // <-- Try this
// Assert
Assert.AreEqual(HttpStatusCode.InternalServerError, response.StatusCode);
Related
This api controller is used to return a pdf stream to display in an html object tag
using AspNetCore.Reporting;
using Microsoft.AspNetCore.Mvc;
[HttpGet, Route("ProcedureRangeForm")]
public IActionResult ProcedureRangeForm(string procedureRangeId, byte procedureTypeId)
{
int extension = 1;
var _reportPath = "";
switch (procedureRangeId)
{
case "1":
_reportPath = #"Reports\ProcedureRangeForm1.rdlc";
break;
case "2":
_reportPath = #"Reports\ProcedureRangeForm2.rdlc";
break;
case "3":
_reportPath = #"Reports\ProcedureRangeForm3.rdlc";
break;
default:
// code block
break;
}
//Employee employee = _context.Employees.FirstOrDefault(x => x.Id == "41")!;
ProcedureType procedureType = _context.ProcedureTypes.FirstOrDefault(x => x.Id == procedureTypeId);
//RelationDegree relationDegree = _context.RelationDegrees.FirstOrDefault(x => x.Id == 1)!;
var reportParams1 = new Dictionary<string, string>();
var reportParams2 = new Dictionary<string, string>();
var reportParams3 = new Dictionary<string, string>();
reportParams1.Add("UnitCode", "UnitCode");
reportParams1.Add("ProcedureType", procedureType!.Name!);
reportParams2.Add("ProcedureType", procedureType!.Name!);
reportParams3.Add("ProcedureType", procedureType!.Name!);
//reportParams1.Add("Attachments", "");
LocalReport localReport = new LocalReport(_reportPath);
FileContentResult fileContentResult;
MemoryStream memory = new();
try
{
ReportResult result = null!;
switch (procedureRangeId)
{
case "1":
result = localReport.Execute(RenderType.Pdf, extension, parameters: reportParams1);
break;
case "2":
result = localReport.Execute(RenderType.Pdf, extension, parameters: reportParams2);
break;
case "3":
result = localReport.Execute(RenderType.Pdf, extension, parameters: reportParams3);
break;
default:
// code block
break;
}
byte[] file = result.MainStream;
fileContentResult = new FileContentResult(file, "application/pdf");
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
return Content(HttpStatusCode.InternalServerError.ToString(), e.Message);
}
finally
{
}
return fileContentResult;
}
I want to call this api more than once with varient parameters. when i call once to display ProcedureRangeForm1.rdlc it run successfully , but when i call again to display ProcedureRangeForm2.rdlc throw this exception
System.FormatException: 'The header contains invalid values at index 0: 'An error occurred during local report processing.;The definition of the report 'Reports\ProcedureRangeForm1.rdl' is invalid. An unexpected error occurred in Report Processing. The process cannot access the file 'hdsktzjh.err' because it is being used by another process.''
After a lot of research, I found a solution to my question:
First, I used nuget package Tmds.ExecFunction by Execute a function in a separate process
as in this link
But I didn't get what I wanted
And then I replaced the library AspNetCore.Reporting by ReportViewerCore.NETCore
as in this link
the problem solved as this code
using Microsoft.Reporting.NETCore;
[Route("api/[controller]")]
[ApiController]
public class ProcedureRangeFormsController : ControllerBase
{
private readonly HousingDbContext _context;
public ProcedureRangeFormsController(HousingDbContext context)
{
_context = context;
}
// GET api/values
[HttpGet, Route("ProcedureRangeForm/{procedureRangeId}/{procedureTypeId}")]
public IActionResult ProcedureRangeForm(string procedureRangeId, string procedureTypeId)
{
var reportPath = "";
switch (procedureRangeId)
{
case "1":
reportPath = "TaxHousing.Reports.ProcedureRangeForm1.rdlc";
break;
case "2":
reportPath = "TaxHousing.Reports.ProcedureRangeForm2.rdlc";
break;
case "3":
reportPath = "TaxHousing.Reports.ProcedureRangeForm3.rdlc";
break;
default:
// code block
break;
}
using var rs = Assembly.GetExecutingAssembly().GetManifestResourceStream(reportPath);
var localReport = new Microsoft.Reporting.NETCore.LocalReport();
localReport.LoadReportDefinition(rs);
var reportParams1 = new[] {
new ReportParameter("ProcedureType", "ProcedureType1"),
new ReportParameter("UnitCode", "UnitCode1")
};
var reportParams2 = new[] {
new ReportParameter("ProcedureType", "ProcedureType2")
};
var reportParams3 = new[] {
new ReportParameter("ProcedureType", "ProcedureType3")
};
byte[] file = null;
switch (procedureRangeId)
{
case "1":
localReport.SetParameters(reportParams1);
break;
case "2":
localReport.SetParameters(reportParams2);
break;
case "3":
localReport.SetParameters(reportParams3);
break;
default:
// code block
break;
}
try
{
file = localReport.Render("PDF");
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
return Content(HttpStatusCode.InternalServerError.ToString(), e.Message);
}
return new FileContentResult(file, "application/pdf");
}
}
I am writing async communication between services so if one goes down the request can't be stopped
so I am doing this scenario
I am turning off my consumer and sending message through the producer
I get a response that the message has been sent successfully
but when I run my consumer on again no message in the queue
Note :
when I don't turn off my consumer i can get my message and consume it
this is my producer code
var factory = new ConnectionFactory() { HostName = "host.docker.internal" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "UserRequestExch", type: ExchangeType.Direct);
UserInfo userInfo = new UserInfo();
userInfo.UserID = GetCurrentUserID();
userInfo.JWT=GetCurrentUserToken();
var mess = System.Text.Json.JsonSerializer.Serialize(userInfo);
var body = Encoding.UTF8.GetBytes(mess);
string RoueKey = "";
switch (Int32.Parse(dataObject["PostponementID"].ToString()))
{
case 1:
RoueKey = "AlonePostponement";
break;
case 2:
RoueKey = "BrotherInServicePostponement";
break;
case 3:
RoueKey = "CashAllowance";
break;
case 4:
RoueKey = "CashAllowancLessThan42";
break;
case 5:
RoueKey = "FixedServiceAllowance";
break;
case 6:
RoueKey = "ObligatoryService";
break;
case 7:
RoueKey = "PostponementOfConvicts";
break;
case 8:
RoueKey = "SchoolPostponement";
break;
case 9:
RoueKey = "TravelApproval";
break;
default:
return NotFound();
}
channel.BasicPublish("UserRequestExch", RoueKey, null, body);
return Ok("The request has been received and is now being processed");
my consumer code :
factory = new ConnectionFactory() { HostName = "host.docker.internal" };
connection = factory.CreateConnection();
channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "UserRequestExch", ExchangeType.Direct);
var queName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queName, exchange: "UserRequestExch", routingKey: "TravelApproval");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var recbody = ea.Body.ToArray();
var recmess = Encoding.UTF8.GetString(recbody);
UserInfo userInfo = JsonSerializer.Deserialize<UserInfo>(recmess);
var User = _context.TravelApprovalDb.Where(x => x.UserID == userInfo.UserID).FirstOrDefault();
if (User == null)
{
int ReqStatuesID = InsertRequestToDB(userInfo.UserID);
SendToExternalAPI(userInfo.JWT, ReqStatuesID);
}
else
{
if (User.DateOfEnd.DateTime > DateTime.Now)
{
int ReqStatuesID = InsertRequestToDB(userInfo.UserID);
SendToExternalAPI(userInfo.JWT, ReqStatuesID);
}
}
channel.BasicAck(deliveryTag:ea.DeliveryTag,multiple:true);
};
channel.BasicConsume(queue: queName, consumer: consumer);
System.Console.Read();
I have applied persistent volume to the rappitMQ in docker-compose
volumes:
- rabbitmq:/var/lib/rabbitmq
or
- ~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/
- ~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq
I removed auto ack and put
channel.BasicAck(deliveryTag:ea.DeliveryTag,multiple:true);
but nothing happened
Trying to return a badrequest if the cardMethod.ID doesn't match the payment ID, but currently it returns a 500 internal server error "Object reference not set to an instance of an object" Where or how would I go about returning an error based off the logic below. I wasn't sure if it should be handled in the controller or should be handed in the service layer.
As currently the service layer handles mostly stripe exceptions.
Or should I try implement a try catch in my controller?
service class
public async Task<VersionResponse> DeletePaymentMethod(string paymentID, string userId)
{
try
{
StripeConfiguration.ApiKey = _appSettings.StripeSecretKey;
var profile = await _userManager.FindByIdAsync(userId);
var stripeId = profile.StripeAccountId;
if (stripeId == null)
throw new ArgumentException("No associated Stripe account found.");
var service = new PaymentMethodService();
//list the payment methods
var cardPaymentMethods = service.ListAutoPaging(new PaymentMethodListOptions
{
Customer = stripeId,
Type = "card"
});
//Detach card which matches with list of payment methods
var cardMethod = cardPaymentMethods.Where(m => m.Id == paymentID).FirstOrDefault();
if(cardMethod.Id != paymentID)
throw new ArgumentException("Payment method not found for specified id.");
await service.DetachAsync(cardMethod.Id, new PaymentMethodDetachOptions());
return new VersionResponse
{
Data = cardPaymentMethods
};
}
catch (Exception ex)
{
throw HandleStripeExceptions(ex);
}
}
PaymentMethodController
[HttpDelete]
[ProducesResponseType(typeof(FluentValidation.Results.ValidationResult), 400)]
public async Task<IActionResult> DeletePaymentMethod(string paymentID)
{
var userId = User.Claims.FirstOrDefault(x => x.Type == "UserID").Value;
var result = new SuccessResponse()
{
success = true
};
await _paymentService.DeletePaymentMethod(paymentID, userId);
if (string.IsNullOrEmpty(paymentID))
return BadRequest("Payment method not found for specified id.");
return Ok(result);
}
private Exception HandleStripeExceptions(Exception ex)
{
if (ex is StripeException e)
{
switch (e.StripeError.ErrorType)
{
case "card_error":
Console.WriteLine("Code: " + e.StripeError.Code);
Console.WriteLine("Message: " + e.StripeError.Message);
break;
case "api_connection_error":
break;
case "api_error":
break;
case "missing_parameter":
break;
case "authentication_error":
break;
case "rate_limit_error":
break;
case "validation_error":
break;
default:
// Unknown Error Type
break;
}
return ex;
}
else
{
return ex;
}
}
I believe the 500 error is a result of
if(cardMethod.Id != paymentID)
throw new ArgumentException("Payment method not found for specified id.");
The cardMethod could be null, you should check null in the if statement like
if(cardMethod == null)
There will no case where cardMethod.Id != paymentID is true.
I have problem when I trying to return task result from task async function my function:
public async Task<IEnumerable<string>> Run()
{
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "API Key",
ApplicationName = this.GetType().ToString()
});
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.Q = "anwar jibawi"; // Replace with your search term.
searchListRequest.MaxResults = 50;
// Call the search.list method to retrieve results matching the specified query term.
var searchListResponse = await searchListRequest.ExecuteAsync();
List<string> videos = new List<string>();
List<string> channels = new List<string>();
List<string> playlists = new List<string>();
// Add each result to the appropriate list, and then display the lists of
// matching videos, channels, and playlists.
foreach (var searchResult in searchListResponse.Items)
{
switch (searchResult.Id.Kind)
{
case "youtube#video":
string thumbnail = searchResult.Snippet.Thumbnails.Default__.Url;
videos.Add(String.Format("{0} ({1}) {2}", searchResult.Snippet.Title, searchResult.Id.VideoId, thumbnail));
break;
case "youtube#channel":
channels.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.ChannelId));
break;
case "youtube#playlist":
playlists.Add(String.Format("{0} ({1})", searchResult.Snippet.Title, searchResult.Id.PlaylistId));
break;
}
}
return videos;
//Console.WriteLine(String.Format("Videos:\n{0}\n", string.Join("\n", videos)));
//Console.WriteLine(String.Format("Channels:\n{0}\n", string.Join("\n", channels)));
//Console.WriteLine(String.Format("Playlists:\n{0}\n", string.Join("\n", playlists)));
}
here I'm calling async function:
public ActionResult Index()
{
Task<IEnumerable<string>> task = new Search().Run();
task.Wait();//if remove this line it will work fine but without any result
var x = task.Result;//if remove this line it will work fine but without any result
return View();
}
Why its hanging when I call task.Wait() or task.Reslut
Assuming this is an ASP.NET application, you shouldn't use .Result (or .Wait()) as it will result in deadlock (as you've found out)
Instead, change your Index method to this
public async Task<ActionResult> Index()
{
var x = await new Search().Run();
return View();
}
I'm trying to debug my c# application that check MIPS syntax. But its not allowing be to debug it. No matter where I enter my break point it gets ignored, including the first line of the Main() function. Its also throwing me this error.
'add a b c' works fine if i don't call HasValidParams()
'add a b' throws exception in the same situation
neither works when calling HasValidParams()
program.cs
private static void Main(string[] args)
{
var validator = new MipsValidator();
Console.Write("Please enter a MIPS statement: ");
string input = Console.ReadLine();
List<string> arguments = input.Split(new char[0]).ToList();
Response status = validator.IsSyntaxValid(arguments);
//Check syntax
if (status.Success.Equals(true))
{
Response stat = validator.HasValidParams(arguments);
//Check parameters
if (stat.Success.Equals(true))
{
Console.WriteLine(string.Format("'{0}' is a valid mips instruction ", input));
}
else
{
foreach (var reason in stat.Reasons)
{
Console.WriteLine(reason);
}
}
}
else
{
foreach (string reason in status.Reasons)
{
Console.WriteLine(reason);
}
}
}
mips-validator.cs
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace mips_validator.utils
{
public class MipsValidator : IMipsValidator
{
#region Implementation of IMipsValidator
public Response IsSyntaxValid(List<string> args)
{
var response = new Response {Success = true};
var op = (Operator) Enum.Parse(typeof (Operator), args[0]);
switch (op)
{
case Operator.addi:
case Operator.add:
case Operator.beq:
if (args.Count != 4)
{
response.Reasons.Add(string.Format("4 operands required for {0}, {1} parameters provided.",
op, args.Count));
response.Success = false;
}
break;
case Operator.j:
if (args.Count != 2)
{
response.Reasons.Add(string.Format("1 operands required for {1}, {0} parameters provided.",
args.Count, op));
response.Success = false;
}
break;
default:
response.Reasons.Add(string.Format("{0} is an unknown mips operation", op));
response.Success = false;
break;
}
return response;
}
public Response HasValidParams(List<string> parameters)
{
string op1, op2, op3;
var temporary = new Regex(#"/\$t\d+/");
var store = new Regex(#"/\$s\d+/");
var zero = new Regex(#"/\$zero/");
var osReserved = new Regex(#"/\$k0|1/");
var memory = new Regex(#"");
var constant = new Regex(#"/-?\d*/");
var label = new Regex(#"/.*\:/");
Operator operation;
var response = new Response {Success = true};
string opString = parameters[0];
Enum.TryParse(opString.Replace("$", string.Empty), true, out operation);
switch (operation)
{
case Operator.add:
{
op1 = parameters[1];
op2 = parameters[2];
if (!temporary.IsMatch(op1) && !store.IsMatch(op1) && !zero.IsMatch(op1))
{
response.Reasons.Add(string.Format("{0}: error register expected", op1));
response.Success = false;
}
if (!temporary.IsMatch(op2) && !store.IsMatch(op2) && !zero.IsMatch(op2))
{
response.Reasons.Add(string.Format("{0}: error register expected", op2));
response.Success = false;
}
}
break;
case Operator.addi:
{
op1 = parameters[1];
op2 = parameters[2];
if (!temporary.IsMatch(op1) && !store.IsMatch(op1) && !zero.IsMatch(op1))
{
response.Reasons.Add(string.Format("{0}: error register expected", op1));
response.Success = false;
}
if (!constant.IsMatch(op2) && !zero.IsMatch(op2))
{
response.Reasons.Add(string.Format("{0}: error constant expected", op2));
response.Success = false;
}
}
break;
case Operator.beq:
{
op1 = parameters[1];
op2 = parameters[2];
op3 = parameters[3];
if (!temporary.IsMatch(op1) && !store.IsMatch(op1) && !zero.IsMatch(op1))
{
response.Reasons.Add(string.Format("{0}: error register expected", op1));
response.Success = false;
}
if (!temporary.IsMatch(op2) && !store.IsMatch(op2) && !zero.IsMatch(op2))
{
response.Reasons.Add(string.Format("{0}: error register expected", op2));
response.Success = false;
}
if (!label.IsMatch(op3) && !constant.IsMatch(op3))
{
response.Reasons.Add(string.Format("{0}: error label or constant expected", op3));
response.Success = false;
}
}
break;
}
return response;
}
#endregion
}
}
SOLUTION-------
Response.cs(old)
public class Response
{
public List<string> Reasons;
public bool Success = true;
}
Response.cs(current)
public class Response
{
public Response()
{
Reasons = new List<string>();
Success = true;
}
public List<string> Reasons;
public bool Success = true;
}
I can't tell if you're looking for a way to be able to debug your project or if you'd prefer to be told potential issues in your code.
For the latter:
Make sure Response.Reasons is initialized by the constructor of Response (or a field initializer).
You're not showing the Response class, so make sure Reasons is actually set to a collection you can add to and not left to the default, null.
Edit: The below possible cause for a crash was pointed put by #nodakai not to be one at all; turns out an empty char array is a special case to split on whitespace.
*You calculate arguments by doing
List arguments = input.Split(new char[0]).ToList();
...which as far as I can tell does absolutely nothing except put the original string inside a List. You probably want to split on new char[] {' '} instead to split on spaces.*
Check if your breakpoint looks like this:
If it does, your source code differs from the code the assembly was actually compiled with. Make sure your project is built properly (right click on the solution and select "Rebuild") and check your current configuration:
Hope this helps...