Reputation: 11
I want to insert a log into the database and throw a UserFriendlyException but it doesn't work as I expect
if (isTodayOpen) //today open but time not valid
{
var logMessage = string.Format("The door cannot be unlocked. Your booking is not yet in effect. It is valid from {0} to {1}. Please try again later.", application.Rules.TimeFrom.ToString(), application.Rules.TimeTo.ToString());
var openDoorLogDetails = new OpenDoorLog();
openDoorLogDetails.ApplicantId = application.User.Id;
openDoorLogDetails.OpenDoorTime = DateTime.Now;
openDoorLogDetails.isOpenSuccessful = false;
openDoorLogDetails.LogMessage = logMessage;
await _openDoorLogRepository.InsertAsync(openDoorLogDetails);
await CurrentUnitOfWork.SaveChangesAsync();
throw new UserFriendlyException(logMessage);
}
what I get on Swagger
{ "result": null, "targetUrl": null, "success": false, "error": { "code": 0, "message": "The door cannot be unlocked. Your booking is not yet in effect. It is valid from 09:00:00 to 10:00:00. Please try again later.", "details": null, "validationErrors": null }, "unAuthorizedRequest": false, "__abp": true }
even though I use the CurrentUnitOfWork.SaveChanges(); it only throws the exception but the log doesn't insert into a database. My expected result is the log can be inserted into the database and can throw UserFriendlyException to the user.
Upvotes: 1
Views: 325
Reputation: 190
First, you should avoid the use of exception as way to handle the logic of your application. That is easier as first but you will have, at some point ,performance issues. (see those insightfull question and question).
Best would be to return from the function the result (return
keyword or the ref
keyword or the out
keyword ?)
Anyway for me the error message seems fine. If you want the minimum update of your code, you can add to your UserFriendlyException field like Context, Problem, Solution. (See there)
[Serializable()]
public class UserFriendlyException : Exception, ISerializable {
public string Context;
// message of exeption used as Problem section
public string Solution;
public UserFriendlyException () : base() { }
public UserFriendlyException (string message) : base(message) { }
public UserFriendlyException (string message, System.Exception inner) : base(message, inner) { }
public UserFriendlyException (SerializationInfo info, StreamingContext context) : base(info, context) { }
public UserFriendlyException (string message, string context, string solution) : base(message) {
this.Context= context;
this.Solution= solution;
}
}
// ...
// In your code
// ...
if (isTodayOpen) //today open but time not valid
{
var logMessage = "The door cannot be unlocked. Your booking is not yet in effect.";
var openDoorLogDetails = new OpenDoorLog();
openDoorLogDetails.ApplicantId = application.User.Id;
openDoorLogDetails.OpenDoorTime = DateTime.Now;
openDoorLogDetails.isOpenSuccessful = false;
openDoorLogDetails.LogMessage = logMessage;
await _openDoorLogRepository.InsertAsync(openDoorLogDetails);
await CurrentUnitOfWork.SaveChangesAsync();
throw new UserFriendlyException(
message: logMessage,
context : "Application booking door is open but time is invalid",
solution : $"It is valid from {application.Rules.TimeFrom.ToString()} to {application.Rules.TimeTo.ToString()}. Please try again later."
);
}
// ...
You will have a reply like that :
{
"__abp": true,
"error": {
"code": 0,
"details": null,
"message": "The door cannot be unlocked. Your booking is not yet in effect.",
"context":"Application booking door is open but time is invalid",
"solution":"It is valid from 09:00:00 to 10:00:00. Please try again later.",
"validationErrors": null
},
"result": null,
"success": false,
"targetUrl": null,
"unAuthorizedRequest": false
}
If you still want the message error only, you can make a try catch at very hight level of your app and catch(UserFriendlyException ex) { return ex.Message}
. But you should define a proper error message template regarding how this data will be consumed (directl by the user ? via front end ?).
Take care
Upvotes: 0
Reputation: 1163
When you want to work with async operation in repository you need to write save changes as below:
await _openDoorLogRepository.InsertAsync(openDoorLogDetails);
await CurrentUnitOfWork.SaveChangesAsync();
Upvotes: 0