aboutsummaryrefslogtreecommitdiff
path: root/BackEnd/Timeline
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-04-30 16:52:55 +0800
committercrupest <crupest@outlook.com>2021-04-30 16:52:55 +0800
commita672e10faad434899d81ef9d0d0d5adbbc7841da (patch)
tree33c18e4bdad7384c748cf08be1f0569f9a8af619 /BackEnd/Timeline
parentb87abbb8ed0aa86a808b2f97e4d22b0ee1addd9f (diff)
downloadtimeline-a672e10faad434899d81ef9d0d0d5adbbc7841da.tar.gz
timeline-a672e10faad434899d81ef9d0d0d5adbbc7841da.tar.bz2
timeline-a672e10faad434899d81ef9d0d0d5adbbc7841da.zip
refactor: ...
Diffstat (limited to 'BackEnd/Timeline')
-rw-r--r--BackEnd/Timeline/Controllers/ActionResultControllerExtensions.cs13
-rw-r--r--BackEnd/Timeline/Controllers/BookmarkTimelineController.cs30
-rw-r--r--BackEnd/Timeline/Controllers/HighlightTimelineController.cs30
-rw-r--r--BackEnd/Timeline/Controllers/Resource.Designer.cs9
-rw-r--r--BackEnd/Timeline/Controllers/Resource.resx3
-rw-r--r--BackEnd/Timeline/Controllers/TimelineController.cs70
-rw-r--r--BackEnd/Timeline/Controllers/TimelinePostController.cs3
-rw-r--r--BackEnd/Timeline/Controllers/TokenController.cs4
-rw-r--r--BackEnd/Timeline/Controllers/UserAvatarController.cs32
-rw-r--r--BackEnd/Timeline/Controllers/UserController.cs53
-rw-r--r--BackEnd/Timeline/ErrorCodes.cs24
-rw-r--r--BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs28
-rw-r--r--BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs40
-rw-r--r--BackEnd/Timeline/Filters/CatchTimelineNotExistExceptionAttribute.cs33
-rw-r--r--BackEnd/Timeline/Filters/CatchTimelinePostDataNotExistExceptionAttribute.cs24
-rw-r--r--BackEnd/Timeline/Filters/CatchTimelinePostNotExistExceptionAttribute.cs24
-rw-r--r--BackEnd/Timeline/Filters/Resource.Designer.cs81
-rw-r--r--BackEnd/Timeline/Filters/Resource.resx126
-rw-r--r--BackEnd/Timeline/Models/Http/ErrorResponse.cs48
-rw-r--r--BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs32
-rw-r--r--BackEnd/Timeline/Services/Api/HighlightTimelineService.cs21
-rw-r--r--BackEnd/Timeline/Services/Api/IBookmarkTimelineService.cs18
-rw-r--r--BackEnd/Timeline/Services/Api/IHighlightTimelineService.cs12
-rw-r--r--BackEnd/Timeline/Services/EntityAlreadyExistException.cs21
-rw-r--r--BackEnd/Timeline/Services/EntityException.cs31
-rw-r--r--BackEnd/Timeline/Services/EntityNames.cs2
-rw-r--r--BackEnd/Timeline/Services/EntityNotExistException.cs16
-rw-r--r--BackEnd/Timeline/Services/EntityType.cs34
-rw-r--r--BackEnd/Timeline/Services/EntityTypes.cs11
-rw-r--r--BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs22
-rw-r--r--BackEnd/Timeline/Services/Timeline/BasicTimelineServiceExtensions.cs17
-rw-r--r--BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs8
-rw-r--r--BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs37
-rw-r--r--BackEnd/Timeline/Services/Timeline/ITimelineService.cs22
-rw-r--r--BackEnd/Timeline/Services/Timeline/TimelineAlreadyExistException.cs24
-rw-r--r--BackEnd/Timeline/Services/Timeline/TimelineNotExistException.cs27
-rw-r--r--BackEnd/Timeline/Services/Timeline/TimelinePostDataNotExistException.cs25
-rw-r--r--BackEnd/Timeline/Services/Timeline/TimelinePostNotExistException.cs36
-rw-r--r--BackEnd/Timeline/Services/Timeline/TimelinePostService.cs72
-rw-r--r--BackEnd/Timeline/Services/Timeline/TimelineService.cs33
-rw-r--r--BackEnd/Timeline/Services/Token/IUserTokenManager.cs2
-rw-r--r--BackEnd/Timeline/Services/Token/UserTokenManager.cs2
-rw-r--r--BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs8
-rw-r--r--BackEnd/Timeline/Services/User/BasicUserService.cs28
-rw-r--r--BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs17
-rw-r--r--BackEnd/Timeline/Services/User/IBasicUserService.cs4
-rw-r--r--BackEnd/Timeline/Services/User/IUserPermissionService.cs6
-rw-r--r--BackEnd/Timeline/Services/User/IUserService.cs8
-rw-r--r--BackEnd/Timeline/Services/User/UserAlreadyExistException.cs24
-rw-r--r--BackEnd/Timeline/Services/User/UserNotExistException.cs37
-rw-r--r--BackEnd/Timeline/Services/User/UserPermissionService.cs10
-rw-r--r--BackEnd/Timeline/Services/User/UserService.cs19
-rw-r--r--BackEnd/Timeline/Startup.cs8
-rw-r--r--BackEnd/Timeline/Timeline.csproj9
54 files changed, 693 insertions, 685 deletions
diff --git a/BackEnd/Timeline/Controllers/ActionResultControllerExtensions.cs b/BackEnd/Timeline/Controllers/ActionResultControllerExtensions.cs
new file mode 100644
index 00000000..76a8b7ae
--- /dev/null
+++ b/BackEnd/Timeline/Controllers/ActionResultControllerExtensions.cs
@@ -0,0 +1,13 @@
+using Microsoft.AspNetCore.Mvc;
+using Timeline.Models.Http;
+
+namespace Timeline.Controllers
+{
+ public static class ActionResultControllerExtensions
+ {
+ public static BadRequestObjectResult BadRequestWithCodeAndMessage(this ControllerBase controller, int code, string message)
+ {
+ return controller.BadRequest(new CommonResponse(code, message));
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs b/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs
index cbc96fc6..94cb0f3e 100644
--- a/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs
+++ b/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs
@@ -60,16 +60,9 @@ namespace Timeline.Controllers
[ProducesResponseType(401)]
public async Task<ActionResult<CommonPutResponse>> Put([GeneralTimelineName] string timeline)
{
- try
- {
- var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
- var create = await _service.AddBookmarkAsync(this.GetUserId(), timelineId);
- return CommonPutResponse.Create(create);
- }
- catch (TimelineNotExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NotExist());
- }
+ var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
+ var create = await _service.AddBookmarkAsync(this.GetUserId(), timelineId);
+ return CommonPutResponse.Create(create);
}
/// <summary>
@@ -83,16 +76,9 @@ namespace Timeline.Controllers
[ProducesResponseType(401)]
public async Task<ActionResult<CommonDeleteResponse>> Delete([GeneralTimelineName] string timeline)
{
- try
- {
- var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
- var delete = await _service.RemoveBookmarkAsync(this.GetUserId(), timelineId);
- return CommonDeleteResponse.Create(delete);
- }
- catch (TimelineNotExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NotExist());
- }
+ var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
+ var delete = await _service.RemoveBookmarkAsync(this.GetUserId(), timelineId);
+ return CommonDeleteResponse.Create(delete);
}
/// <summary>
@@ -112,10 +98,6 @@ namespace Timeline.Controllers
await _service.MoveBookmarkAsync(this.GetUserId(), timelineId, request.NewPosition!.Value);
return Ok();
}
- catch (TimelineNotExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NotExist());
- }
catch (InvalidBookmarkException)
{
return BadRequest(new CommonResponse(ErrorCodes.BookmarkTimelineController.NonBookmark, "You can't move a non-bookmark timeline."));
diff --git a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs
index ffaa50c1..e73bc7a9 100644
--- a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs
+++ b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs
@@ -60,16 +60,9 @@ namespace Timeline.Controllers
[ProducesResponseType(403)]
public async Task<ActionResult<CommonPutResponse>> Put([GeneralTimelineName] string timeline)
{
- try
- {
- var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
- var create = await _service.AddHighlightTimelineAsync(timelineId, this.GetUserId());
- return CommonPutResponse.Create(create);
- }
- catch (TimelineNotExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NotExist());
- }
+ var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
+ var create = await _service.AddHighlightTimelineAsync(timelineId, this.GetUserId());
+ return CommonPutResponse.Create(create);
}
/// <summary>
@@ -84,16 +77,9 @@ namespace Timeline.Controllers
[ProducesResponseType(403)]
public async Task<ActionResult<CommonDeleteResponse>> Delete([GeneralTimelineName] string timeline)
{
- try
- {
- var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
- var delete = await _service.RemoveHighlightTimelineAsync(timelineId, this.GetUserId());
- return CommonDeleteResponse.Create(delete);
- }
- catch (TimelineNotExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NotExist());
- }
+ var timelineId = await _timelineService.GetTimelineIdByNameAsync(timeline);
+ var delete = await _service.RemoveHighlightTimelineAsync(timelineId, this.GetUserId());
+ return CommonDeleteResponse.Create(delete);
}
/// <summary>
@@ -113,10 +99,6 @@ namespace Timeline.Controllers
await _service.MoveHighlightTimelineAsync(timelineId, body.NewPosition!.Value);
return Ok();
}
- catch (TimelineNotExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NotExist());
- }
catch (InvalidHighlightTimelineException)
{
return BadRequest(new CommonResponse(ErrorCodes.HighlightTimelineController.NonHighlight, "Can't move a non-highlight timeline."));
diff --git a/BackEnd/Timeline/Controllers/Resource.Designer.cs b/BackEnd/Timeline/Controllers/Resource.Designer.cs
index 6279a055..c2dfd3cd 100644
--- a/BackEnd/Timeline/Controllers/Resource.Designer.cs
+++ b/BackEnd/Timeline/Controllers/Resource.Designer.cs
@@ -68,5 +68,14 @@ namespace Timeline.Controllers {
return ResourceManager.GetString("ExceptionNoUserId", resourceCulture);
}
}
+
+ /// <summary>
+ /// Looks up a localized string similar to A user with given username already exists..
+ /// </summary>
+ internal static string MessageUsernameConflict {
+ get {
+ return ResourceManager.GetString("MessageUsernameConflict", resourceCulture);
+ }
+ }
}
}
diff --git a/BackEnd/Timeline/Controllers/Resource.resx b/BackEnd/Timeline/Controllers/Resource.resx
index ec45a5c9..8939dfd8 100644
--- a/BackEnd/Timeline/Controllers/Resource.resx
+++ b/BackEnd/Timeline/Controllers/Resource.resx
@@ -120,4 +120,7 @@
<data name="ExceptionNoUserId" xml:space="preserve">
<value>Can't get user id.</value>
</data>
+ <data name="MessageUsernameConflict" xml:space="preserve">
+ <value>A user with given username already exists.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/BackEnd/Timeline/Controllers/TimelineController.cs b/BackEnd/Timeline/Controllers/TimelineController.cs
index 3fd0f2ac..bb770ea0 100644
--- a/BackEnd/Timeline/Controllers/TimelineController.cs
+++ b/BackEnd/Timeline/Controllers/TimelineController.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Timeline.Entities;
-using Timeline.Filters;
using Timeline.Models;
using Timeline.Models.Http;
using Timeline.Models.Validation;
@@ -21,7 +20,6 @@ namespace Timeline.Controllers
/// </summary>
[ApiController]
[Route("timelines")]
- [CatchTimelineNotExistException]
[ProducesErrorResponseType(typeof(CommonResponse))]
public class TimelineController : Controller
{
@@ -100,7 +98,7 @@ namespace Timeline.Controllers
relationship = new TimelineUserRelationship(relationType, relatedUserId);
}
- catch (UserNotExistException)
+ catch (EntityNotExistException)
{
return BadRequest(ErrorResponse.TimelineController.QueryRelateNotExist());
}
@@ -148,17 +146,10 @@ namespace Timeline.Controllers
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
- try
- {
- await _service.ChangePropertyAsync(timelineId, _mapper.AutoMapperMap<TimelineChangePropertyParams>(body));
- var t = await _service.GetTimelineAsync(timelineId);
- var result = await Map(t);
- return result;
- }
- catch (EntityAlreadyExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NameConflict());
- }
+ await _service.ChangePropertyAsync(timelineId, _mapper.AutoMapperMap<TimelineChangePropertyParams>(body));
+ var t = await _service.GetTimelineAsync(timelineId);
+ var result = await Map(t);
+ return result;
}
/// <summary>
@@ -181,16 +172,9 @@ namespace Timeline.Controllers
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
- try
- {
- var userId = await _userService.GetUserIdByUsernameAsync(member);
- var create = await _service.AddMemberAsync(timelineId, userId);
- return Ok(CommonPutResponse.Create(create));
- }
- catch (UserNotExistException)
- {
- return BadRequest(ErrorResponse.UserCommon.NotExist());
- }
+ var userId = await _userService.GetUserIdByUsernameAsync(member);
+ var create = await _service.AddMemberAsync(timelineId, userId);
+ return Ok(CommonPutResponse.Create(create));
}
/// <summary>
@@ -213,16 +197,10 @@ namespace Timeline.Controllers
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
- try
- {
- var userId = await _userService.GetUserIdByUsernameAsync(member);
- var delete = await _service.RemoveMemberAsync(timelineId, userId);
- return Ok(CommonDeleteResponse.Create(delete));
- }
- catch (UserNotExistException)
- {
- return BadRequest(ErrorResponse.UserCommon.NotExist());
- }
+
+ var userId = await _userService.GetUserIdByUsernameAsync(member);
+ var delete = await _service.RemoveMemberAsync(timelineId, userId);
+ return Ok(CommonDeleteResponse.Create(delete));
}
/// <summary>
@@ -239,16 +217,9 @@ namespace Timeline.Controllers
{
var userId = this.GetUserId();
- try
- {
- var timeline = await _service.CreateTimelineAsync(body.Name, userId);
- var result = await Map(timeline);
- return result;
- }
- catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.Timeline)
- {
- return BadRequest(ErrorResponse.TimelineController.NameConflict());
- }
+ var timeline = await _service.CreateTimelineAsync(body.Name, userId);
+ var result = await Map(timeline);
+ return result;
}
/// <summary>
@@ -271,15 +242,8 @@ namespace Timeline.Controllers
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
- try
- {
- await _service.DeleteTimelineAsync(timelineId);
- return Ok();
- }
- catch (TimelineNotExistException)
- {
- return BadRequest(ErrorResponse.TimelineController.NotExist());
- }
+ await _service.DeleteTimelineAsync(timelineId);
+ return Ok();
}
}
}
diff --git a/BackEnd/Timeline/Controllers/TimelinePostController.cs b/BackEnd/Timeline/Controllers/TimelinePostController.cs
index 2d3e5423..70f672d1 100644
--- a/BackEnd/Timeline/Controllers/TimelinePostController.cs
+++ b/BackEnd/Timeline/Controllers/TimelinePostController.cs
@@ -22,9 +22,6 @@ namespace Timeline.Controllers
/// </summary>
[ApiController]
[Route("timelines/{timeline}/posts")]
- [CatchTimelineNotExistException]
- [CatchTimelinePostNotExistException]
- [CatchTimelinePostDataNotExistException]
[ProducesErrorResponseType(typeof(CommonResponse))]
public class TimelinePostController : Controller
{
diff --git a/BackEnd/Timeline/Controllers/TokenController.cs b/BackEnd/Timeline/Controllers/TokenController.cs
index 3d4e9444..915f710d 100644
--- a/BackEnd/Timeline/Controllers/TokenController.cs
+++ b/BackEnd/Timeline/Controllers/TokenController.cs
@@ -44,7 +44,7 @@ namespace Timeline.Controllers
try
{
DateTime? expireTime = null;
- if (request.Expire != null)
+ if (request.Expire is not null)
expireTime = _clock.GetCurrentTime().AddDays(request.Expire.Value);
var result = await _userTokenManager.CreateTokenAsync(request.Username, request.Password, expireTime);
@@ -55,7 +55,7 @@ namespace Timeline.Controllers
User = await _mapper.MapAsync<HttpUser>(result.User, Url, User)
};
}
- catch (UserNotExistException)
+ catch (EntityNotExistException)
{
return BadRequest(ErrorResponse.TokenController.Create_BadCredential());
}
diff --git a/BackEnd/Timeline/Controllers/UserAvatarController.cs b/BackEnd/Timeline/Controllers/UserAvatarController.cs
index b1129329..5d9becaa 100644
--- a/BackEnd/Timeline/Controllers/UserAvatarController.cs
+++ b/BackEnd/Timeline/Controllers/UserAvatarController.cs
@@ -44,16 +44,8 @@ namespace Timeline.Controllers
public async Task<IActionResult> Get([FromRoute][Username] string username, [FromHeader(Name = "If-None-Match")] string? ifNoneMatch)
{
_ = ifNoneMatch;
- try
- {
- long userId = await _userService.GetUserIdByUsernameAsync(username);
- return await DataCacheHelper.GenerateActionResult(this, () => _service.GetAvatarDigestAsync(userId), () => _service.GetAvatarAsync(userId));
- }
- catch (UserNotExistException)
- {
- return NotFound(ErrorResponse.UserCommon.NotExist());
- }
-
+ long userId = await _userService.GetUserIdByUsernameAsync(username);
+ return await DataCacheHelper.GenerateActionResult(this, () => _service.GetAvatarDigestAsync(userId), () => _service.GetAvatarAsync(userId));
}
/// <summary>
@@ -76,15 +68,7 @@ namespace Timeline.Controllers
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
- long id;
- try
- {
- id = await _userService.GetUserIdByUsernameAsync(username);
- }
- catch (UserNotExistException)
- {
- return BadRequest(ErrorResponse.UserCommon.NotExist());
- }
+ long id = await _userService.GetUserIdByUsernameAsync(username);
try
{
@@ -127,15 +111,7 @@ namespace Timeline.Controllers
return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
}
- long id;
- try
- {
- id = await _userService.GetUserIdByUsernameAsync(username);
- }
- catch (UserNotExistException)
- {
- return BadRequest(ErrorResponse.UserCommon.NotExist());
- }
+ long id = await _userService.GetUserIdByUsernameAsync(username);
await _service.DeleteAvatarAsync(id);
return Ok();
diff --git a/BackEnd/Timeline/Controllers/UserController.cs b/BackEnd/Timeline/Controllers/UserController.cs
index c0ae6a09..bdf9c0b7 100644
--- a/BackEnd/Timeline/Controllers/UserController.cs
+++ b/BackEnd/Timeline/Controllers/UserController.cs
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
using Timeline.Auth;
using Timeline.Models.Http;
using Timeline.Models.Validation;
-using Timeline.Services;
using Timeline.Services.Mapper;
using Timeline.Services.User;
@@ -59,16 +58,10 @@ namespace Timeline.Controllers
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<HttpUser>> Post([FromBody] HttpUserPostRequest body)
{
- try
- {
- var user = await _userService.CreateUserAsync(
- new CreateUserParams(body.Username, body.Password) { Nickname = body.Nickname });
- return await _mapper.MapAsync<HttpUser>(user, Url, User);
- }
- catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.User)
- {
- return BadRequest(ErrorResponse.UserController.UsernameConflict());
- }
+
+ var user = await _userService.CreateUserAsync(
+ new CreateUserParams(body.Username, body.Password) { Nickname = body.Nickname });
+ return await _mapper.MapAsync<HttpUser>(user, Url, User);
}
/// <summary>
@@ -81,16 +74,9 @@ namespace Timeline.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<HttpUser>> Get([FromRoute][Username] string username)
{
- try
- {
- var id = await _userService.GetUserIdByUsernameAsync(username);
- var user = await _userService.GetUserAsync(id);
- return await _mapper.MapAsync<HttpUser>(user, Url, User);
- }
- catch (UserNotExistException)
- {
- return NotFound(ErrorResponse.UserCommon.NotExist());
- }
+ var id = await _userService.GetUserIdByUsernameAsync(username);
+ var user = await _userService.GetUserAsync(id);
+ return await _mapper.MapAsync<HttpUser>(user, Url, User);
}
/// <summary>
@@ -109,20 +95,9 @@ namespace Timeline.Controllers
{
if (UserHasUserManagementPermission)
{
- try
- {
- var id = await _userService.GetUserIdByUsernameAsync(username);
- var user = await _userService.ModifyUserAsync(id, _mapper.AutoMapperMap<ModifyUserParams>(body));
- return await _mapper.MapAsync<HttpUser>(user, Url, User);
- }
- catch (UserNotExistException)
- {
- return NotFound(ErrorResponse.UserCommon.NotExist());
- }
- catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.User)
- {
- return BadRequest(ErrorResponse.UserController.UsernameConflict());
- }
+ var id = await _userService.GetUserIdByUsernameAsync(username);
+ var user = await _userService.ModifyUserAsync(id, _mapper.AutoMapperMap<ModifyUserParams>(body));
+ return await _mapper.MapAsync<HttpUser>(user, Url, User);
}
else
{
@@ -204,10 +179,6 @@ namespace Timeline.Controllers
await _userPermissionService.AddPermissionToUserAsync(id, permission);
return Ok();
}
- catch (UserNotExistException)
- {
- return NotFound(ErrorResponse.UserCommon.NotExist());
- }
catch (InvalidOperationOnRootUserException)
{
return BadRequest(ErrorResponse.UserController.ChangePermission_RootUser());
@@ -228,10 +199,6 @@ namespace Timeline.Controllers
await _userPermissionService.RemovePermissionFromUserAsync(id, permission);
return Ok();
}
- catch (UserNotExistException)
- {
- return NotFound(ErrorResponse.UserCommon.NotExist());
- }
catch (InvalidOperationOnRootUserException)
{
return BadRequest(ErrorResponse.UserController.ChangePermission_RootUser());
diff --git a/BackEnd/Timeline/ErrorCodes.cs b/BackEnd/Timeline/ErrorCodes.cs
index 87d451f2..06952822 100644
--- a/BackEnd/Timeline/ErrorCodes.cs
+++ b/BackEnd/Timeline/ErrorCodes.cs
@@ -1,4 +1,4 @@
-namespace Timeline.Models.Http
+namespace Timeline
{
/// <summary>
/// All error code constants.
@@ -36,9 +36,22 @@
}
}
- public static class UserCommon
+ public static class NotExist
{
- public const int NotExist = 1_001_0001;
+ public const int Default = 2_001_00_00;
+ public const int User = 2_001_00_01;
+ public const int Timeline = 2_001_00_02;
+ public const int TimelinePost = 2_001_00_03;
+ public const int TimelinePostData = 2_001_00_04;
+ }
+
+ public static class Conflict
+ {
+ public const int Default = 2_002_00_00;
+ public const int User = 2_002_00_01;
+ public const int Timeline = 2_002_00_02;
+ public const int TimelinePost = 2_002_00_03;
+ public const int TimelinePostData = 2_002_00_04;
}
public static class TokenController
@@ -52,7 +65,6 @@
public static class UserController
{
- public const int UsernameConflict = 1_102_01_01;
public const int ChangePassword_BadOldPassword = 1_102_02_01;
public const int ChangePermission_RootUser = 1_102_03_01;
public const int Delete_RootUser = 1_102_04_01;
@@ -67,11 +79,7 @@
public static class TimelineController
{
- public const int NameConflict = 1_104_01_01;
- public const int NotExist = 1_104_02_01;
public const int QueryRelateNotExist = 1_104_04_01;
- public const int PostNotExist = 1_104_05_01;
- public const int PostDataNotExist = 1_104_05_02;
}
public static class HighlightTimelineController
diff --git a/BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs b/BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs
new file mode 100644
index 00000000..67b260d2
--- /dev/null
+++ b/BackEnd/Timeline/Filters/CatchEntityAlreadyExistExceptionFilter.cs
@@ -0,0 +1,28 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Timeline.Models.Http;
+using Timeline.Services;
+
+namespace Timeline.Filters
+{
+ public class CatchEntityAlreadyExistExceptionFilter : IExceptionFilter
+ {
+ private static string MakeMessage(EntityAlreadyExistException e)
+ {
+ return string.Format(Resource.MessageEntityAlreadyExist, e.EntityType.Name, e.GenerateConstraintString());
+ }
+
+ private static CommonResponse MakeCommonResponse(EntityAlreadyExistException e)
+ {
+ return new CommonResponse(e.EntityType.ConflictErrorCode, MakeMessage(e));
+ }
+
+ public void OnException(ExceptionContext context)
+ {
+ if (context.Exception is EntityAlreadyExistException e)
+ {
+ context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
+ }
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs b/BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs
new file mode 100644
index 00000000..225fab4f
--- /dev/null
+++ b/BackEnd/Timeline/Filters/CatchEntityNotExistExceptionFilter.cs
@@ -0,0 +1,40 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Timeline.Models.Http;
+using Timeline.Services;
+
+namespace Timeline.Filters
+{
+ public class CatchEntityNotExistExceptionFilter : IExceptionFilter
+ {
+ private static string MakeMessage(EntityNotExistException e)
+ {
+ return string.Format(Resource.MessageEntityNotExist, e.EntityType.Name, e.GenerateConstraintString());
+ }
+
+ private static CommonResponse MakeCommonResponse(EntityNotExistException e)
+ {
+ return new CommonResponse(e.EntityType.NotExistErrorCode, MakeMessage(e));
+ }
+
+ public void OnException(ExceptionContext context)
+ {
+ if (context.Exception is EntityNotExistException e)
+ {
+ if (HttpMethods.IsGet(context.HttpContext.Request.Method))
+ {
+ context.Result = new NotFoundObjectResult(MakeCommonResponse(e));
+ }
+ else if (HttpMethods.IsDelete(context.HttpContext.Request.Method))
+ {
+ context.Result = new OkObjectResult(CommonDeleteResponse.NotExist());
+ }
+ else
+ {
+ context.Result = new BadRequestObjectResult(MakeCommonResponse(e));
+ }
+ }
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Filters/CatchTimelineNotExistExceptionAttribute.cs b/BackEnd/Timeline/Filters/CatchTimelineNotExistExceptionAttribute.cs
deleted file mode 100644
index 7a1352a3..00000000
--- a/BackEnd/Timeline/Filters/CatchTimelineNotExistExceptionAttribute.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Timeline.Models.Http;
-using Timeline.Services.Timeline;
-using Timeline.Services.User;
-
-namespace Timeline.Filters
-{
- public class CatchTimelineNotExistExceptionAttribute : ExceptionFilterAttribute
- {
- public override void OnException(ExceptionContext context)
- {
- if (context.Exception is TimelineNotExistException e)
- {
- if (e.InnerException is UserNotExistException)
- {
- if (HttpMethods.IsGet(context.HttpContext.Request.Method))
- context.Result = new NotFoundObjectResult(ErrorResponse.UserCommon.NotExist());
- else
- context.Result = new BadRequestObjectResult(ErrorResponse.UserCommon.NotExist());
- }
- else
- {
- if (HttpMethods.IsGet(context.HttpContext.Request.Method))
- context.Result = new NotFoundObjectResult(ErrorResponse.TimelineController.NotExist());
- else
- context.Result = new BadRequestObjectResult(ErrorResponse.TimelineController.NotExist());
- }
- }
- }
- }
-}
diff --git a/BackEnd/Timeline/Filters/CatchTimelinePostDataNotExistExceptionAttribute.cs b/BackEnd/Timeline/Filters/CatchTimelinePostDataNotExistExceptionAttribute.cs
deleted file mode 100644
index b4046c58..00000000
--- a/BackEnd/Timeline/Filters/CatchTimelinePostDataNotExistExceptionAttribute.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Timeline.Models.Http;
-using Timeline.Services.Timeline;
-
-namespace Timeline.Filters
-{
- public class CatchTimelinePostDataNotExistExceptionAttribute : ExceptionFilterAttribute
- {
- public override void OnException(ExceptionContext context)
- {
- const string message = "Timeline post data does not exist.";
-
- if (context.Exception is TimelinePostDataNotExistException e)
- {
- if (HttpMethods.IsGet(context.HttpContext.Request.Method))
- context.Result = new NotFoundObjectResult(new CommonResponse(ErrorCodes.TimelineController.PostNotExist, message));
- else
- context.Result = new BadRequestObjectResult(new CommonResponse(ErrorCodes.TimelineController.PostNotExist, message));
- }
- }
- }
-}
diff --git a/BackEnd/Timeline/Filters/CatchTimelinePostNotExistExceptionAttribute.cs b/BackEnd/Timeline/Filters/CatchTimelinePostNotExistExceptionAttribute.cs
deleted file mode 100644
index a288f890..00000000
--- a/BackEnd/Timeline/Filters/CatchTimelinePostNotExistExceptionAttribute.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Timeline.Models.Http;
-using Timeline.Services.Timeline;
-
-namespace Timeline.Filters
-{
- public class CatchTimelinePostNotExistExceptionAttribute : ExceptionFilterAttribute
- {
- public override void OnException(ExceptionContext context)
- {
- const string message = "Timeline post does not exist.";
-
- if (context.Exception is TimelinePostNotExistException e)
- {
- if (HttpMethods.IsGet(context.HttpContext.Request.Method))
- context.Result = new NotFoundObjectResult(new CommonResponse(ErrorCodes.TimelineController.PostNotExist, message));
- else
- context.Result = new BadRequestObjectResult(new CommonResponse(ErrorCodes.TimelineController.PostNotExist, message));
- }
- }
- }
-}
diff --git a/BackEnd/Timeline/Filters/Resource.Designer.cs b/BackEnd/Timeline/Filters/Resource.Designer.cs
new file mode 100644
index 00000000..8ae6d288
--- /dev/null
+++ b/BackEnd/Timeline/Filters/Resource.Designer.cs
@@ -0,0 +1,81 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Timeline.Filters {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resource {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resource() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Timeline.Filters.Resource", typeof(Resource).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The entity you want to create already exists. Entity type is {0}. Constraints are {1}..
+ /// </summary>
+ internal static string MessageEntityAlreadyExist {
+ get {
+ return ResourceManager.GetString("MessageEntityAlreadyExist", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The entity you operate on does not exist. Entity type is {0}. Constraints are {1}..
+ /// </summary>
+ internal static string MessageEntityNotExist {
+ get {
+ return ResourceManager.GetString("MessageEntityNotExist", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Filters/Resource.resx b/BackEnd/Timeline/Filters/Resource.resx
new file mode 100644
index 00000000..e9a5fbf9
--- /dev/null
+++ b/BackEnd/Timeline/Filters/Resource.resx
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="MessageEntityAlreadyExist" xml:space="preserve">
+ <value>The entity you want to create already exists. Entity type is {0}. Constraints are {1}.</value>
+ </data>
+ <data name="MessageEntityNotExist" xml:space="preserve">
+ <value>The entity you operate on does not exist. Entity type is {0}. Constraints are {1}.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/BackEnd/Timeline/Models/Http/ErrorResponse.cs b/BackEnd/Timeline/Models/Http/ErrorResponse.cs
index 3812471d..7ab520a7 100644
--- a/BackEnd/Timeline/Models/Http/ErrorResponse.cs
+++ b/BackEnd/Timeline/Models/Http/ErrorResponse.cs
@@ -66,20 +66,6 @@ namespace Timeline.Models.Http
}
- public static class UserCommon
- {
- public static CommonResponse NotExist(params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.UserCommon.NotExist, string.Format(UserCommon_NotExist, formatArgs));
- }
-
- public static CommonResponse CustomMessage_NotExist(string message, params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.UserCommon.NotExist, string.Format(message, formatArgs));
- }
-
- }
-
public static class TokenController
{
public static CommonResponse Create_BadCredential(params object?[] formatArgs)
@@ -136,16 +122,6 @@ namespace Timeline.Models.Http
public static class UserController
{
- public static CommonResponse UsernameConflict(params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.UserController.UsernameConflict, string.Format(UserController_UsernameConflict, formatArgs));
- }
-
- public static CommonResponse CustomMessage_UsernameConflict(string message, params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.UserController.UsernameConflict, string.Format(message, formatArgs));
- }
-
public static CommonResponse ChangePassword_BadOldPassword(params object?[] formatArgs)
{
return new CommonResponse(ErrorCodes.UserController.ChangePassword_BadOldPassword, string.Format(UserController_ChangePassword_BadOldPassword, formatArgs));
@@ -214,26 +190,6 @@ namespace Timeline.Models.Http
public static class TimelineController
{
- public static CommonResponse NameConflict(params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.TimelineController.NameConflict, string.Format(TimelineController_NameConflict, formatArgs));
- }
-
- public static CommonResponse CustomMessage_NameConflict(string message, params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.TimelineController.NameConflict, string.Format(message, formatArgs));
- }
-
- public static CommonResponse NotExist(params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.TimelineController.NotExist, string.Format(TimelineController_NotExist, formatArgs));
- }
-
- public static CommonResponse CustomMessage_NotExist(string message, params object?[] formatArgs)
- {
- return new CommonResponse(ErrorCodes.TimelineController.NotExist, string.Format(message, formatArgs));
- }
-
public static CommonResponse QueryRelateNotExist(params object?[] formatArgs)
{
return new CommonResponse(ErrorCodes.TimelineController.QueryRelateNotExist, string.Format(TimelineController_QueryRelateNotExist, formatArgs));
@@ -246,12 +202,12 @@ namespace Timeline.Models.Http
public static CommonResponse PostNotExist(params object?[] formatArgs)
{
- return new CommonResponse(ErrorCodes.TimelineController.PostNotExist, string.Format(TimelineController_PostNotExist, formatArgs));
+ return new CommonResponse(ErrorCodes.NotExist.TimelinePost, string.Format(TimelineController_PostNotExist, formatArgs));
}
public static CommonResponse CustomMessage_PostNotExist(string message, params object?[] formatArgs)
{
- return new CommonResponse(ErrorCodes.TimelineController.PostNotExist, string.Format(message, formatArgs));
+ return new CommonResponse(ErrorCodes.NotExist.TimelinePost, string.Format(message, formatArgs));
}
}
diff --git a/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs b/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs
index 4fc20ecb..de70a9db 100644
--- a/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs
+++ b/BackEnd/Timeline/Services/Api/BookmarkTimelineService.cs
@@ -24,11 +24,8 @@ namespace Timeline.Services.Api
public async Task<bool> AddBookmarkAsync(long userId, long timelineId)
{
- if (!await _userService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
-
- if (!await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ await _userService.ThrowIfUserNotExist(userId);
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
if (await _database.BookmarkTimelines.AnyAsync(t => t.TimelineId == timelineId && t.UserId == userId))
return false;
@@ -46,8 +43,7 @@ namespace Timeline.Services.Api
public async Task<List<long>> GetBookmarksAsync(long userId)
{
- if (!await _userService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
+ await _userService.ThrowIfUserNotExist(userId);
var entities = await _database.BookmarkTimelines.Where(t => t.UserId == userId).OrderBy(t => t.Rank).Select(t => new { t.TimelineId }).ToListAsync();
@@ -56,22 +52,19 @@ namespace Timeline.Services.Api
public async Task<bool> IsBookmarkAsync(long userId, long timelineId, bool checkUserExistence = true, bool checkTimelineExistence = true)
{
- if (checkUserExistence && !await _userService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
+ if (checkUserExistence)
+ await _userService.ThrowIfUserNotExist(userId);
- if (checkTimelineExistence && !await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ if (checkTimelineExistence)
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
return await _database.BookmarkTimelines.AnyAsync(b => b.TimelineId == timelineId && b.UserId == userId);
}
public async Task MoveBookmarkAsync(long userId, long timelineId, long newPosition)
{
- if (!await _userService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
-
- if (!await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ await _userService.ThrowIfUserNotExist(userId);
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
var entity = await _database.BookmarkTimelines.SingleOrDefaultAsync(t => t.TimelineId == timelineId && t.UserId == userId);
@@ -109,11 +102,8 @@ namespace Timeline.Services.Api
public async Task<bool> RemoveBookmarkAsync(long userId, long timelineId)
{
- if (!await _userService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
-
- if (!await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ await _userService.ThrowIfUserNotExist(userId);
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
var entity = await _database.BookmarkTimelines.SingleOrDefaultAsync(t => t.UserId == userId && t.TimelineId == timelineId);
diff --git a/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs b/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs
index a9d831ab..d4367e57 100644
--- a/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs
+++ b/BackEnd/Timeline/Services/Api/HighlightTimelineService.cs
@@ -25,12 +25,11 @@ namespace Timeline.Services.Api
public async Task<bool> AddHighlightTimelineAsync(long timelineId, long? operatorId)
{
- if (!await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
- if (operatorId.HasValue && !await _userService.CheckUserExistenceAsync(operatorId.Value))
+ if (operatorId.HasValue)
{
- throw new UserNotExistException(null, operatorId.Value, "User with given operator id does not exist.", null);
+ await _userService.ThrowIfUserNotExist(operatorId.Value);
}
var alreadyIs = await _database.HighlightTimelines.AnyAsync(t => t.TimelineId == timelineId);
@@ -51,12 +50,11 @@ namespace Timeline.Services.Api
public async Task<bool> RemoveHighlightTimelineAsync(long timelineId, long? operatorId)
{
- if (!await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
- if (operatorId.HasValue && !await _userService.CheckUserExistenceAsync(operatorId.Value))
+ if (operatorId.HasValue)
{
- throw new UserNotExistException(null, operatorId.Value, "User with given operator id does not exist.", null);
+ await _userService.ThrowIfUserNotExist(operatorId.Value);
}
var entity = await _database.HighlightTimelines.SingleOrDefaultAsync(t => t.TimelineId == timelineId);
@@ -79,8 +77,7 @@ namespace Timeline.Services.Api
public async Task MoveHighlightTimelineAsync(long timelineId, long newPosition)
{
- if (!await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
var entity = await _database.HighlightTimelines.SingleOrDefaultAsync(t => t.TimelineId == timelineId);
@@ -118,8 +115,8 @@ namespace Timeline.Services.Api
public async Task<bool> IsHighlightTimelineAsync(long timelineId, bool checkTimelineExistence = true)
{
- if (checkTimelineExistence && !await _timelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ if (checkTimelineExistence)
+ await _timelineService.ThrowIfTimelineNotExist(timelineId);
return await _database.HighlightTimelines.AnyAsync(t => t.TimelineId == timelineId);
}
diff --git a/BackEnd/Timeline/Services/Api/IBookmarkTimelineService.cs b/BackEnd/Timeline/Services/Api/IBookmarkTimelineService.cs
index 18feee54..63b4affa 100644
--- a/BackEnd/Timeline/Services/Api/IBookmarkTimelineService.cs
+++ b/BackEnd/Timeline/Services/Api/IBookmarkTimelineService.cs
@@ -15,7 +15,7 @@ namespace Timeline.Services.Api
/// </summary>
/// <param name="userId">User id of bookmark owner.</param>
/// <returns>Id of Bookmark timelines in order.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
Task<List<long>> GetBookmarksAsync(long userId);
/// <summary>
@@ -26,8 +26,8 @@ namespace Timeline.Services.Api
/// <param name="checkUserExistence">If true it will throw when user does not exist.</param>
/// <param name="checkTimelineExistence">If true it will throw when timeline does not exist.</param>
/// <returns>True if timeline is a bookmark. Otherwise false.</returns>
- /// <exception cref="UserNotExistException">Throw if user does not exist and <paramref name="checkUserExistence"/> is true.</exception>
- /// <exception cref="TimelineNotExistException">Thrown if timeline does not exist and <paramref name="checkTimelineExistence"/> is true.</exception>
+ /// <exception cref="EntityNotExistException">Throw if user does not exist and <paramref name="checkUserExistence"/> is true.</exception>
+ /// <exception cref="EntityNotExistException">Thrown if timeline does not exist and <paramref name="checkTimelineExistence"/> is true.</exception>
Task<bool> IsBookmarkAsync(long userId, long timelineId, bool checkUserExistence = true, bool checkTimelineExistence = true);
/// <summary>
@@ -36,8 +36,8 @@ namespace Timeline.Services.Api
/// <param name="userId">User id of bookmark owner.</param>
/// <param name="timelineId">Timeline id.</param>
/// <returns>True if timeline is added to bookmark. False if it already is.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
Task<bool> AddBookmarkAsync(long userId, long timelineId);
/// <summary>
@@ -46,8 +46,8 @@ namespace Timeline.Services.Api
/// <param name="userId">User id of bookmark owner.</param>
/// <param name="timelineId">Timeline id.</param>
/// <returns>True if deletion is performed. False if bookmark does not exist.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
Task<bool> RemoveBookmarkAsync(long userId, long timelineId);
/// <summary>
@@ -56,8 +56,8 @@ namespace Timeline.Services.Api
/// <param name="userId">User id of bookmark owner.</param>
/// <param name="timelineId">Timeline name.</param>
/// <param name="newPosition">New position. Starts at 1.</param>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
/// <exception cref="InvalidBookmarkException">Thrown when the timeline is not a bookmark.</exception>
Task MoveBookmarkAsync(long userId, long timelineId, long newPosition);
}
diff --git a/BackEnd/Timeline/Services/Api/IHighlightTimelineService.cs b/BackEnd/Timeline/Services/Api/IHighlightTimelineService.cs
index 4f14d19b..2e488778 100644
--- a/BackEnd/Timeline/Services/Api/IHighlightTimelineService.cs
+++ b/BackEnd/Timeline/Services/Api/IHighlightTimelineService.cs
@@ -22,7 +22,7 @@ namespace Timeline.Services.Api
/// <param name="timelineId">Timeline id.</param>
/// <param name="checkTimelineExistence">If true it will throw if timeline does not exist.</param>
/// <returns>True if timeline is highlight. Otherwise false.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist and <paramref name="checkTimelineExistence"/> is true.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist and <paramref name="checkTimelineExistence"/> is true.</exception>
Task<bool> IsHighlightTimelineAsync(long timelineId, bool checkTimelineExistence = true);
/// <summary>
@@ -31,8 +31,8 @@ namespace Timeline.Services.Api
/// <param name="timelineId">The timeline id.</param>
/// <param name="operatorId">The user id of operator.</param>
/// <returns>True if timeline is actually added to highligh. False if it already is.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline with given id does not exist.</exception>
- /// <exception cref="UserNotExistException">Thrown when user with given operator id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline with given id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user with given operator id does not exist.</exception>
Task<bool> AddHighlightTimelineAsync(long timelineId, long? operatorId);
/// <summary>
@@ -41,8 +41,8 @@ namespace Timeline.Services.Api
/// <param name="timelineId">The timeline id.</param>
/// <param name="operatorId">The user id of operator.</param>
/// <returns>True if deletion is actually performed. Otherwise false (timeline was not in the list).</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline with given id does not exist.</exception>
- /// <exception cref="UserNotExistException">Thrown when user with given operator id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline with given id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user with given operator id does not exist.</exception>
Task<bool> RemoveHighlightTimelineAsync(long timelineId, long? operatorId);
/// <summary>
@@ -50,7 +50,7 @@ namespace Timeline.Services.Api
/// </summary>
/// <param name="timelineId">The timeline name.</param>
/// <param name="newPosition">The new position. Starts at 1.</param>
- /// <exception cref="TimelineNotExistException">Thrown when timeline with given id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline with given id does not exist.</exception>
/// <exception cref="InvalidHighlightTimelineException">Thrown when given timeline is not a highlight timeline.</exception>
/// <remarks>
/// If <paramref name="newPosition"/> is smaller than 1. Then move the timeline to head.
diff --git a/BackEnd/Timeline/Services/EntityAlreadyExistException.cs b/BackEnd/Timeline/Services/EntityAlreadyExistException.cs
index 2d3de368..0aaea012 100644
--- a/BackEnd/Timeline/Services/EntityAlreadyExistException.cs
+++ b/BackEnd/Timeline/Services/EntityAlreadyExistException.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace Timeline.Services
{
@@ -9,24 +10,18 @@ namespace Timeline.Services
/// For example, want to create a timeline but a timeline with the same name already exists.
/// </remarks>
[Serializable]
- public class EntityAlreadyExistException : Exception
+ public class EntityAlreadyExistException : EntityException
{
- public EntityAlreadyExistException() : this(null, null, null, null) { }
- public EntityAlreadyExistException(string? entityName) : this(entityName, null, null, null) { }
- public EntityAlreadyExistException(string? entityName, Exception? inner) : this(entityName, null, null, inner) { }
- public EntityAlreadyExistException(string? entityName, object? entity, Exception inner) : this(entityName, entity, null, inner) { }
- public EntityAlreadyExistException(string? entityName, object? entity, string? message, Exception? inner) : base(message ?? Resource.ExceptionEntityAlreadyExist, inner)
+ public EntityAlreadyExistException() : base() { }
+ public EntityAlreadyExistException(string? message) : base(message) { }
+ public EntityAlreadyExistException(string? message, Exception? inner) : base(message, inner) { }
+ public EntityAlreadyExistException(EntityType entityType, IDictionary<string, object> constraints, string? message = null, Exception? inner = null)
+ : base(entityType, constraints, message ?? Resource.ExceptionEntityNotExist, inner)
{
- EntityName = entityName;
- Entity = entity;
- }
+ }
protected EntityAlreadyExistException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
-
- public string? EntityName { get; }
-
- public object? Entity { get; }
}
}
diff --git a/BackEnd/Timeline/Services/EntityException.cs b/BackEnd/Timeline/Services/EntityException.cs
new file mode 100644
index 00000000..7a302e5a
--- /dev/null
+++ b/BackEnd/Timeline/Services/EntityException.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Timeline.Services
+{
+ [Serializable]
+ public class EntityException : Exception
+ {
+ public EntityException() { }
+ public EntityException(string? message) : base(message) { }
+ public EntityException(string? message, Exception? inner) : base(message, inner) { }
+ public EntityException(EntityType entityType, IDictionary<string, object> constraints, string? message = null, Exception? inner = null)
+ : base(message, inner)
+ {
+ EntityType = entityType;
+ Constraints = constraints;
+ }
+ protected EntityException(
+ System.Runtime.Serialization.SerializationInfo info,
+ System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
+
+ public EntityType EntityType { get; } = EntityTypes.Default;
+ public IDictionary<string, object> Constraints { get; } = new Dictionary<string, object>();
+
+ public string GenerateConstraintString()
+ {
+ return string.Join(' ', Constraints.Select(c => $"[{c.Key} = {c.Value}]"));
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Services/EntityNames.cs b/BackEnd/Timeline/Services/EntityNames.cs
index 7dae6a4a..5df5e615 100644
--- a/BackEnd/Timeline/Services/EntityNames.cs
+++ b/BackEnd/Timeline/Services/EntityNames.cs
@@ -2,8 +2,10 @@
{
public static class EntityNames
{
+ public const string Default = "Default";
public const string User = "User";
public const string Timeline = "Timeline";
public const string TimelinePost = "TimelinePost";
+ public const string TimelinePostData = "TimelinePostData";
}
}
diff --git a/BackEnd/Timeline/Services/EntityNotExistException.cs b/BackEnd/Timeline/Services/EntityNotExistException.cs
index 39a4f545..0c836fc4 100644
--- a/BackEnd/Timeline/Services/EntityNotExistException.cs
+++ b/BackEnd/Timeline/Services/EntityNotExistException.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace Timeline.Services
{
@@ -9,19 +10,18 @@ namespace Timeline.Services
/// For example, you want to get a timeline with given name but it does not exist.
/// </example>
[Serializable]
- public class EntityNotExistException : Exception
+ public class EntityNotExistException : EntityException
{
- public EntityNotExistException() : this(null, null) { }
- public EntityNotExistException(string? entityName) : this(entityName, null) { }
- public EntityNotExistException(string? entityName, Exception? inner) : this(entityName, null, inner) { }
- public EntityNotExistException(string? entityName, string? message, Exception? inner) : base(message ?? Resource.ExceptionEntityNotExist, inner)
+ public EntityNotExistException() : base() { }
+ public EntityNotExistException(string? message) : base(message) { }
+ public EntityNotExistException(string? message, Exception? inner) : base(message, inner) { }
+ public EntityNotExistException(EntityType entityType, IDictionary<string, object> constraints, string? message = null, Exception? inner = null)
+ : base(entityType, constraints, message ?? Resource.ExceptionEntityNotExist, inner)
{
- EntityName = entityName;
+
}
protected EntityNotExistException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
-
- public string? EntityName { get; }
}
}
diff --git a/BackEnd/Timeline/Services/EntityType.cs b/BackEnd/Timeline/Services/EntityType.cs
new file mode 100644
index 00000000..c379d211
--- /dev/null
+++ b/BackEnd/Timeline/Services/EntityType.cs
@@ -0,0 +1,34 @@
+using System.Reflection;
+
+namespace Timeline.Services
+{
+ public class EntityType
+ {
+ public EntityType(string name)
+ {
+ Name = name;
+ }
+
+ public string Name { get; }
+
+ public int NotExistErrorCode
+ {
+ get
+ {
+ var field = typeof(ErrorCodes.NotExist).GetField(Name, BindingFlags.Public | BindingFlags.Static);
+ if (field is not null) return (int)field.GetRawConstantValue()!;
+ return ErrorCodes.NotExist.Default;
+ }
+ }
+
+ public int ConflictErrorCode
+ {
+ get
+ {
+ var field = typeof(ErrorCodes.Conflict).GetField(Name, BindingFlags.Public | BindingFlags.Static);
+ if (field is not null) return (int)field.GetRawConstantValue()!;
+ return ErrorCodes.Conflict.Default;
+ }
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Services/EntityTypes.cs b/BackEnd/Timeline/Services/EntityTypes.cs
new file mode 100644
index 00000000..d4884fd6
--- /dev/null
+++ b/BackEnd/Timeline/Services/EntityTypes.cs
@@ -0,0 +1,11 @@
+namespace Timeline.Services
+{
+ public static class EntityTypes
+ {
+ public static EntityType Default { get; } = new EntityType(EntityNames.Default);
+ public static EntityType User { get; } = new EntityType(EntityNames.User);
+ public static EntityType Timeline { get; } = new EntityType(EntityNames.Timeline);
+ public static EntityType TimelinePost { get; } = new EntityType(EntityNames.TimelinePost);
+ public static EntityType TimelinePostData { get; } = new EntityType(EntityNames.TimelinePostData);
+ }
+}
diff --git a/BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs b/BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs
index 7476a860..360f6c63 100644
--- a/BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs
+++ b/BackEnd/Timeline/Services/Timeline/BasicTimelineService.cs
@@ -47,6 +47,22 @@ namespace Timeline.Services.Timeline
};
}
+ protected static EntityNotExistException CreateTimelineNotExistException(string name, Exception? inner = null)
+ {
+ return new EntityNotExistException(EntityTypes.Timeline, new Dictionary<string, object>
+ {
+ ["name"] = name
+ }, null, inner);
+ }
+
+ protected static EntityNotExistException CreateTimelineNotExistException(long id)
+ {
+ return new EntityNotExistException(EntityTypes.Timeline, new Dictionary<string, object>
+ {
+ ["id"] = id
+ });
+ }
+
protected void CheckGeneralTimelineName(string timelineName, string? paramName)
{
if (!_generalTimelineNameValidator.Validate(timelineName, out var message))
@@ -75,9 +91,9 @@ namespace Timeline.Services.Timeline
{
userId = await _basicUserService.GetUserIdByUsernameAsync(username);
}
- catch (UserNotExistException e)
+ catch (EntityNotExistException e)
{
- throw new TimelineNotExistException(timelineName, e);
+ throw CreateTimelineNotExistException(timelineName, e);
}
var timelineEntity = await _database.Timelines.Where(t => t.OwnerId == userId && t.Name == null).Select(t => new { t.Id }).SingleOrDefaultAsync();
@@ -103,7 +119,7 @@ namespace Timeline.Services.Timeline
if (timelineEntity == null)
{
- throw new TimelineNotExistException(timelineName);
+ throw CreateTimelineNotExistException(timelineName);
}
else
{
diff --git a/BackEnd/Timeline/Services/Timeline/BasicTimelineServiceExtensions.cs b/BackEnd/Timeline/Services/Timeline/BasicTimelineServiceExtensions.cs
new file mode 100644
index 00000000..4075c9c0
--- /dev/null
+++ b/BackEnd/Timeline/Services/Timeline/BasicTimelineServiceExtensions.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Timeline.Services.Timeline
+{
+ public static class BasicTimelineServiceExtensions
+ {
+ public static async Task ThrowIfTimelineNotExist(this IBasicTimelineService service, long timelineId)
+ {
+ if (!await service.CheckTimelineExistenceAsync(timelineId))
+ {
+ throw new EntityNotExistException(EntityTypes.Timeline,
+ new Dictionary<string, object> { ["id"] = timelineId });
+ }
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs b/BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs
index b32fa3f7..b6f1e6de 100644
--- a/BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs
+++ b/BackEnd/Timeline/Services/Timeline/IBasicTimelineService.cs
@@ -1,6 +1,5 @@
using System;
using System.Threading.Tasks;
-using Timeline.Services.User;
namespace Timeline.Services.Timeline
{
@@ -23,14 +22,9 @@ namespace Timeline.Services.Timeline
/// <returns>Id of the timeline.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="timelineName"/> is null.</exception>
/// <exception cref="ArgumentException">Throw when <paramref name="timelineName"/> is of bad format.</exception>
- /// <exception cref="TimelineNotExistException">
+ /// <exception cref="EntityNotExistException">
/// Thrown when timeline with name <paramref name="timelineName"/> does not exist.
- /// If it is a personal timeline, then inner exception is <see cref="UserNotExistException"/>.
/// </exception>
- /// <remarks>
- /// If name is of personal timeline and the timeline does not exist, it will be created if user exists.
- /// If the user does not exist, <see cref="TimelineNotExistException"/> will be thrown with <see cref="UserNotExistException"/> as inner exception.
- ///</remarks>
Task<long> GetTimelineIdByNameAsync(string timelineName);
}
}
diff --git a/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs b/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs
index 50af9fc2..d746cf63 100644
--- a/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs
+++ b/BackEnd/Timeline/Services/Timeline/ITimelinePostService.cs
@@ -5,7 +5,6 @@ using Timeline.Entities;
using Timeline.Helpers.Cache;
using Timeline.Models;
using Timeline.Services.Imaging;
-using Timeline.Services.User;
namespace Timeline.Services.Timeline
{
@@ -18,7 +17,7 @@ namespace Timeline.Services.Timeline
/// <param name="modifiedSince">The time that posts have been modified since.</param>
/// <param name="includeDeleted">Whether include deleted posts.</param>
/// <returns>A list of all posts.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
Task<List<TimelinePostEntity>> GetPostsAsync(long timelineId, DateTime? modifiedSince = null, bool includeDeleted = false);
/// <summary>
@@ -28,8 +27,8 @@ namespace Timeline.Services.Timeline
/// <param name="postId">The id of the post.</param>
/// <param name="includeDeleted">If true, return the entity even if it is deleted.</param>
/// <returns>The post.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="TimelinePostNotExistException">Thrown when post of <paramref name="postId"/> does not exist or has been deleted.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when post of <paramref name="postId"/> does not exist or has been deleted.</exception>
Task<TimelinePostEntity> GetPostAsync(long timelineId, long postId, bool includeDeleted = false);
/// <summary>
@@ -39,9 +38,9 @@ namespace Timeline.Services.Timeline
/// <param name="postId">The post id.</param>
/// <param name="dataIndex">The index of the data.</param>
/// <returns>The data digest.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="TimelinePostNotExistException">Thrown when post of <paramref name="postId"/> does not exist or has been deleted.</exception>
- /// <exception cref="TimelinePostDataNotExistException">Thrown when data of that index does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when post of <paramref name="postId"/> does not exist or has been deleted.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when data of that index does not exist.</exception>
Task<ICacheableDataDigest> GetPostDataDigestAsync(long timelineId, long postId, long dataIndex);
/// <summary>
@@ -51,9 +50,9 @@ namespace Timeline.Services.Timeline
/// <param name="postId">The post id.</param>
/// <param name="dataIndex">The index of the data.</param>
/// <returns>The data.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="TimelinePostNotExistException">Thrown when post of <paramref name="postId"/> does not exist or has been deleted.</exception>
- /// <exception cref="TimelinePostDataNotExistException">Thrown when data of that index does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when post of <paramref name="postId"/> does not exist or has been deleted.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when data of that index does not exist.</exception>
Task<ByteData> GetPostDataAsync(long timelineId, long postId, long dataIndex);
/// <summary>
@@ -65,8 +64,8 @@ namespace Timeline.Services.Timeline
/// <returns>The entity of the created post.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="request"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="request"/> is of invalid format.</exception>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="UserNotExistException">Thrown if user of <paramref name="authorId"/> does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown if user of <paramref name="authorId"/> does not exist.</exception>
/// <exception cref="ImageException">Thrown if data is not a image. Validated by <see cref="ImageService"/>.</exception>
Task<TimelinePostEntity> CreatePostAsync(long timelineId, long authorId, TimelinePostCreateRequest request);
@@ -79,8 +78,8 @@ namespace Timeline.Services.Timeline
/// <returns>The entity of the patched post.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="request"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="request"/> is of invalid format.</exception>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="TimelinePostNotExistException">Thrown when post does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when post does not exist.</exception>
Task<TimelinePostEntity> PatchPostAsync(long timelineId, long postId, TimelinePostPatchRequest request);
/// <summary>
@@ -88,8 +87,8 @@ namespace Timeline.Services.Timeline
/// </summary>
/// <param name="timelineId">The id of the timeline to delete post against.</param>
/// <param name="postId">The id of the post to delete.</param>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="TimelinePostNotExistException">Thrown when the post with given id does not exist or is deleted already.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the post with given id does not exist or is deleted already.</exception>
/// <remarks>
/// First use <see cref="HasPostModifyPermissionAsync(long, long, long, bool)"/> to check the permission.
/// </remarks>
@@ -107,10 +106,10 @@ namespace Timeline.Services.Timeline
/// <param name="timelineId">The id of the timeline.</param>
/// <param name="postId">The id of the post.</param>
/// <param name="modifierId">The id of the user to check on.</param>
- /// <param name="throwOnPostNotExist">True if you want it to throw <see cref="TimelinePostNotExistException"/>. Default false.</param>
+ /// <param name="throwOnPostNotExist">True if you want it to throw <see cref="EntityNotExistException"/>. Default false.</param>
/// <returns>True if can modify, false if can't modify.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="TimelinePostNotExistException">Thrown when the post with given id does not exist or is deleted already and <paramref name="throwOnPostNotExist"/> is true.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the post with given id does not exist or is deleted already and <paramref name="throwOnPostNotExist"/> is true.</exception>
/// <remarks>
/// Unless <paramref name="throwOnPostNotExist"/> is true, this method should return true if the post does not exist.
/// If the post is deleted, its author info still exists, so it is checked as the post is not deleted unless <paramref name="throwOnPostNotExist"/> is true.
diff --git a/BackEnd/Timeline/Services/Timeline/ITimelineService.cs b/BackEnd/Timeline/Services/Timeline/ITimelineService.cs
index 9c313b0b..b371e9e0 100644
--- a/BackEnd/Timeline/Services/Timeline/ITimelineService.cs
+++ b/BackEnd/Timeline/Services/Timeline/ITimelineService.cs
@@ -17,7 +17,7 @@ namespace Timeline.Services.Timeline
/// </summary>
/// <param name="id">Id of timeline.</param>
/// <returns>The timeline info.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
Task<TimelineEntity> GetTimelineAsync(long id);
/// <summary>
@@ -26,7 +26,7 @@ namespace Timeline.Services.Timeline
/// <param name="id">The id of the timeline.</param>
/// <param name="newProperties">The new properties. Null member means not to change.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="newProperties"/> is null.</exception>
- /// <exception cref="TimelineNotExistException">Thrown when timeline with given id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline with given id does not exist.</exception>
/// <exception cref="EntityAlreadyExistException">Thrown when a timeline with new name already exists.</exception>
Task ChangePropertyAsync(long id, TimelineChangePropertyParams newProperties);
@@ -36,8 +36,8 @@ namespace Timeline.Services.Timeline
/// <param name="timelineId">Timeline id.</param>
/// <param name="userId">User id.</param>
/// <returns>True if the memeber was added. False if it is already a member.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="UserNotExistException">Thrown when the user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the user does not exist.</exception>
Task<bool> AddMemberAsync(long timelineId, long userId);
/// <summary>
@@ -46,8 +46,8 @@ namespace Timeline.Services.Timeline
/// <param name="timelineId">Timeline id.</param>
/// <param name="userId">User id.</param>
/// <returns>True if the memeber was removed. False if it was not a member before.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
- /// <exception cref="UserNotExistException">Thrown when the user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the user does not exist.</exception>
Task<bool> RemoveMemberAsync(long timelineId, long userId);
/// <summary>
@@ -56,7 +56,7 @@ namespace Timeline.Services.Timeline
/// <param name="timelineId">The id of the timeline.</param>
/// <param name="userId">The id of the user to check on.</param>
/// <returns>True if the user can manage the timeline, otherwise false.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
/// <remarks>
/// This method does not check whether visitor is administrator.
/// Return false if user with user id does not exist.
@@ -69,7 +69,7 @@ namespace Timeline.Services.Timeline
/// <param name="timelineId">The id of the timeline.</param>
/// <param name="visitorId">The id of the user to check on. Null means visitor without account.</param>
/// <returns>True if can read, false if can't read.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
/// <remarks>
/// This method does not check whether visitor is administrator.
/// Return false if user with visitor id does not exist.
@@ -82,7 +82,7 @@ namespace Timeline.Services.Timeline
/// <param name="timelineId">The id of the timeline.</param>
/// <param name="userId">The id of user to check on.</param>
/// <returns>True if it is a member, false if not.</returns>
- /// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when timeline does not exist.</exception>
/// <remarks>
/// Timeline owner is also considered as a member.
/// Return false when user with user id does not exist.
@@ -109,14 +109,14 @@ namespace Timeline.Services.Timeline
/// <exception cref="ArgumentNullException">Thrown when <paramref name="timelineName"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when timeline name is invalid.</exception>
/// <exception cref="EntityAlreadyExistException">Thrown when the timeline already exists.</exception>
- /// <exception cref="UserNotExistException">Thrown when the owner user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the owner user does not exist.</exception>
Task<TimelineEntity> CreateTimelineAsync(string timelineName, long ownerId);
/// <summary>
/// Delete a timeline.
/// </summary>
/// <param name="id">The id of the timeline to delete.</param>
- /// <exception cref="TimelineNotExistException">Thrown when the timeline does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the timeline does not exist.</exception>
Task DeleteTimelineAsync(long id);
}
}
diff --git a/BackEnd/Timeline/Services/Timeline/TimelineAlreadyExistException.cs b/BackEnd/Timeline/Services/Timeline/TimelineAlreadyExistException.cs
deleted file mode 100644
index 11fc4ef8..00000000
--- a/BackEnd/Timeline/Services/Timeline/TimelineAlreadyExistException.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-
-namespace Timeline.Services.Timeline
-{
- /// <summary>
- /// The user requested does not exist.
- /// </summary>
- [Serializable]
- public class TimelineAlreadyExistException : EntityAlreadyExistException
- {
- public TimelineAlreadyExistException() : this(null, null, null) { }
- public TimelineAlreadyExistException(object? entity) : this(entity, null, null) { }
- public TimelineAlreadyExistException(object? entity, Exception? inner) : this(entity, null, inner) { }
- public TimelineAlreadyExistException(object? entity, string? message, Exception? inner)
- : base(EntityNames.Timeline, entity, message ?? Resource.ExceptionTimelineAlreadyExist, inner)
- {
-
- }
-
- protected TimelineAlreadyExistException(
- System.Runtime.Serialization.SerializationInfo info,
- System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
-}
diff --git a/BackEnd/Timeline/Services/Timeline/TimelineNotExistException.cs b/BackEnd/Timeline/Services/Timeline/TimelineNotExistException.cs
deleted file mode 100644
index 2cfbdedf..00000000
--- a/BackEnd/Timeline/Services/Timeline/TimelineNotExistException.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-
-namespace Timeline.Services.Timeline
-{
- [Serializable]
- public class TimelineNotExistException : EntityNotExistException
- {
- public TimelineNotExistException() : this(null, null, null, null) { }
- public TimelineNotExistException(long? id) : this(null, id, null, null) { }
- public TimelineNotExistException(long? id, Exception? inner) : this(null, id, null, inner) { }
- public TimelineNotExistException(string? timelineName) : this(timelineName, null, null, null) { }
- public TimelineNotExistException(string? timelineName, Exception? inner) : this(timelineName, null, null, inner) { }
- public TimelineNotExistException(string? timelineName, long? timelineId, string? message, Exception? inner = null)
- : base(EntityNames.Timeline, message ?? Resource.ExceptionTimelineNotExist, inner)
- {
- TimelineId = timelineId;
- TimelineName = timelineName;
- }
-
- protected TimelineNotExistException(
- System.Runtime.Serialization.SerializationInfo info,
- System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
-
- public string? TimelineName { get; set; }
- public long? TimelineId { get; set; }
- }
-}
diff --git a/BackEnd/Timeline/Services/Timeline/TimelinePostDataNotExistException.cs b/BackEnd/Timeline/Services/Timeline/TimelinePostDataNotExistException.cs
deleted file mode 100644
index 177973a3..00000000
--- a/BackEnd/Timeline/Services/Timeline/TimelinePostDataNotExistException.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-
-namespace Timeline.Services.Timeline
-{
- [Serializable]
- public class TimelinePostDataNotExistException : Exception
- {
- public TimelinePostDataNotExistException() : this(null, null) { }
- public TimelinePostDataNotExistException(string? message) : this(message, null) { }
- public TimelinePostDataNotExistException(string? message, Exception? inner) : base(message, inner) { }
- public TimelinePostDataNotExistException(long timelineId, long postId, long dataIndex, string? message = null, Exception? inner = null) : base(message, inner)
- {
- TimelineId = timelineId;
- PostId = postId;
- DataIndex = dataIndex;
- }
- protected TimelinePostDataNotExistException(
- System.Runtime.Serialization.SerializationInfo info,
- System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
-
- public long TimelineId { get; set; }
- public long PostId { get; set; }
- public long DataIndex { get; set; }
- }
-}
diff --git a/BackEnd/Timeline/Services/Timeline/TimelinePostNotExistException.cs b/BackEnd/Timeline/Services/Timeline/TimelinePostNotExistException.cs
deleted file mode 100644
index 87c190ab..00000000
--- a/BackEnd/Timeline/Services/Timeline/TimelinePostNotExistException.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Globalization;
-
-namespace Timeline.Services.Timeline
-{
- [Serializable]
- public class TimelinePostNotExistException : EntityNotExistException
- {
- public TimelinePostNotExistException() : this(null, null, false, null, null) { }
- public TimelinePostNotExistException(string? message) : this(message, null) { }
- public TimelinePostNotExistException(string? message, Exception? inner) : this(null, null, false, message, inner) { }
- protected TimelinePostNotExistException(
- System.Runtime.Serialization.SerializationInfo info,
- System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public TimelinePostNotExistException(long? timelineId, long? postId, bool isDelete, string? message = null, Exception? inner = null)
- : base(EntityNames.TimelinePost, message ?? MakeMessage(isDelete), inner)
- {
- TimelineId = timelineId;
- PostId = postId;
- IsDelete = isDelete;
- }
-
- private static string MakeMessage(bool isDelete)
- {
- return string.Format(CultureInfo.CurrentCulture, Resource.ExceptionTimelinePostNoExist, isDelete ? Resource.ExceptionTimelinePostNoExistReasonDeleted : Resource.ExceptionTimelinePostNoExistReasonNotCreated);
- }
-
- public long? TimelineId { get; set; }
- public long? PostId { get; set; }
-
- /// <summary>
- /// True if the post is deleted. False if the post does not exist at all.
- /// </summary>
- public bool IsDelete { get; set; }
- }
-}
diff --git a/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs b/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs
index a9bb7bd1..a0961a8d 100644
--- a/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs
+++ b/BackEnd/Timeline/Services/Timeline/TimelinePostService.cs
@@ -38,27 +38,35 @@ namespace Timeline.Services.Timeline
_clock = clock;
}
- private async Task CheckTimelineExistence(long timelineId)
+ private void CheckColor(string color, string paramName)
{
- if (!await _basicTimelineService.CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ if (!_colorValidator.Validate(color, out var message))
+ throw new ArgumentException(string.Format(Resource.ExceptionColorInvalid, message), paramName);
}
- private async Task CheckUserExistence(long userId)
+ private static EntityNotExistException CreatePostNotExistException(long timelineId, long postId, bool deleted)
{
- if (!await _basicUserService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
+ return new EntityNotExistException(EntityTypes.TimelinePost, new Dictionary<string, object>
+ {
+ ["timeline-id"] = timelineId,
+ ["post-id"] = postId,
+ ["deleted"] = deleted
+ });
}
- private void CheckColor(string color, string paramName)
+ private static EntityNotExistException CreatePostDataNotExistException(long timelineId, long postId, long dataIndex)
{
- if (!_colorValidator.Validate(color, out var message))
- throw new ArgumentException(string.Format(Resource.ExceptionColorInvalid, message), paramName);
+ return new EntityNotExistException(EntityTypes.TimelinePost, new Dictionary<string, object>
+ {
+ ["timeline-id"] = timelineId,
+ ["post-id"] = postId,
+ ["data-index"] = dataIndex
+ });
}
public async Task<List<TimelinePostEntity>> GetPostsAsync(long timelineId, DateTime? modifiedSince = null, bool includeDeleted = false)
{
- await CheckTimelineExistence(timelineId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
modifiedSince = modifiedSince?.MyToUtc();
@@ -81,18 +89,18 @@ namespace Timeline.Services.Timeline
public async Task<TimelinePostEntity> GetPostAsync(long timelineId, long postId, bool includeDeleted = false)
{
- await CheckTimelineExistence(timelineId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
var post = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).SingleOrDefaultAsync();
if (post is null)
{
- throw new TimelinePostNotExistException(timelineId, postId, false);
+ throw CreatePostNotExistException(timelineId, postId, false);
}
if (!includeDeleted && post.Deleted)
{
- throw new TimelinePostNotExistException(timelineId, postId, true);
+ throw CreatePostNotExistException(timelineId, postId, true);
}
return post;
@@ -100,40 +108,40 @@ namespace Timeline.Services.Timeline
public async Task<ICacheableDataDigest> GetPostDataDigestAsync(long timelineId, long postId, long dataIndex)
{
- await CheckTimelineExistence(timelineId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
var postEntity = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).Select(p => new { p.Id, p.Deleted }).SingleOrDefaultAsync();
if (postEntity is null)
- throw new TimelinePostNotExistException(timelineId, postId, false);
+ throw CreatePostNotExistException(timelineId, postId, false);
if (postEntity.Deleted)
- throw new TimelinePostNotExistException(timelineId, postId, true);
+ throw CreatePostNotExistException(timelineId, postId, true);
var dataEntity = await _database.TimelinePostData.Where(d => d.PostId == postEntity.Id && d.Index == dataIndex).SingleOrDefaultAsync();
if (dataEntity is null)
- throw new TimelinePostDataNotExistException(timelineId, postId, dataIndex);
+ throw CreatePostDataNotExistException(timelineId, postId, dataIndex);
return new CacheableDataDigest(dataEntity.DataTag, dataEntity.LastUpdated);
}
public async Task<ByteData> GetPostDataAsync(long timelineId, long postId, long dataIndex)
{
- await CheckTimelineExistence(timelineId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
var postEntity = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).Select(p => new { p.Id, p.Deleted }).SingleOrDefaultAsync();
if (postEntity is null)
- throw new TimelinePostNotExistException(timelineId, postId, false);
+ throw CreatePostNotExistException(timelineId, postId, false);
if (postEntity.Deleted)
- throw new TimelinePostNotExistException(timelineId, postId, true);
+ throw CreatePostNotExistException(timelineId, postId, true);
var dataEntity = await _database.TimelinePostData.Where(d => d.PostId == postEntity.Id && d.Index == dataIndex).SingleOrDefaultAsync();
if (dataEntity is null)
- throw new TimelinePostDataNotExistException(timelineId, postId, dataIndex);
+ throw CreatePostDataNotExistException(timelineId, postId, dataIndex);
var data = await _dataManager.GetEntryAndCheck(dataEntity.DataTag, $"Timeline {timelineId}, post {postId}, data {dataIndex} requires this data.");
@@ -194,8 +202,8 @@ namespace Timeline.Services.Timeline
request.Time = request.Time?.MyToUtc();
- await CheckTimelineExistence(timelineId);
- await CheckUserExistence(authorId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
+ await _basicUserService.ThrowIfUserNotExist(authorId);
var currentTime = _clock.GetCurrentTime();
var finalTime = request.Time ?? currentTime;
@@ -253,15 +261,15 @@ namespace Timeline.Services.Timeline
request.Time = request.Time?.MyToUtc();
- await CheckTimelineExistence(timelineId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
var entity = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).SingleOrDefaultAsync();
if (entity is null)
- throw new TimelinePostNotExistException(timelineId, postId, false);
+ throw CreatePostNotExistException(timelineId, postId, false);
if (entity.Deleted)
- throw new TimelinePostNotExistException(timelineId, postId, true);
+ throw CreatePostNotExistException(timelineId, postId, true);
if (request.Time.HasValue)
entity.Time = request.Time.Value;
@@ -279,15 +287,15 @@ namespace Timeline.Services.Timeline
public async Task DeletePostAsync(long timelineId, long postId)
{
- await CheckTimelineExistence(timelineId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
var entity = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).SingleOrDefaultAsync();
if (entity == null)
- throw new TimelinePostNotExistException(timelineId, postId, false);
+ throw CreatePostNotExistException(timelineId, postId, false);
if (entity.Deleted)
- throw new TimelinePostNotExistException(timelineId, postId, true);
+ throw CreatePostNotExistException(timelineId, postId, true);
await using var transaction = await _database.Database.BeginTransactionAsync();
@@ -321,7 +329,7 @@ namespace Timeline.Services.Timeline
public async Task<bool> HasPostModifyPermissionAsync(long timelineId, long postId, long modifierId, bool throwOnPostNotExist = false)
{
- await CheckTimelineExistence(timelineId);
+ await _basicTimelineService.ThrowIfTimelineNotExist(timelineId);
var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).Select(t => new { t.OwnerId }).SingleAsync();
@@ -330,14 +338,14 @@ namespace Timeline.Services.Timeline
if (postEntity is null)
{
if (throwOnPostNotExist)
- throw new TimelinePostNotExistException(timelineId, postId, false);
+ throw CreatePostNotExistException(timelineId, postId, false);
else
return true;
}
if (postEntity.Deleted && throwOnPostNotExist)
{
- throw new TimelinePostNotExistException(timelineId, postId, true);
+ throw CreatePostNotExistException(timelineId, postId, true);
}
return timelineEntity.OwnerId == modifierId || postEntity.AuthorId == modifierId;
diff --git a/BackEnd/Timeline/Services/Timeline/TimelineService.cs b/BackEnd/Timeline/Services/Timeline/TimelineService.cs
index bde0210a..920fcc74 100644
--- a/BackEnd/Timeline/Services/Timeline/TimelineService.cs
+++ b/BackEnd/Timeline/Services/Timeline/TimelineService.cs
@@ -34,6 +34,13 @@ namespace Timeline.Services.Timeline
_clock = clock;
}
+ private static EntityAlreadyExistException CreateTimelineConflictException(string name)
+ {
+ return new EntityAlreadyExistException(EntityTypes.Timeline, new Dictionary<string, object>
+ {
+ ["name"] = name
+ });
+ }
private void CheckTimelineName(string name, string paramName)
{
@@ -48,7 +55,7 @@ namespace Timeline.Services.Timeline
var entity = await _database.Timelines.Where(t => t.Id == id).SingleOrDefaultAsync();
if (entity is null)
- throw new TimelineNotExistException(id);
+ throw CreateTimelineNotExistException(id);
return entity;
}
@@ -73,7 +80,7 @@ namespace Timeline.Services.Timeline
var entity = await _database.Timelines.Where(t => t.Id == id).SingleOrDefaultAsync();
if (entity is null)
- throw new TimelineNotExistException(id);
+ throw CreateTimelineNotExistException(id);
var changed = false;
var nameChanged = false;
@@ -83,7 +90,7 @@ namespace Timeline.Services.Timeline
var conflict = await _database.Timelines.AnyAsync(t => t.Name == newProperties.Name);
if (conflict)
- throw new TimelineAlreadyExistException();
+ throw CreateTimelineConflictException(newProperties.Name);
entity.Name = newProperties.Name;
@@ -130,10 +137,9 @@ namespace Timeline.Services.Timeline
public async Task<bool> AddMemberAsync(long timelineId, long userId)
{
if (!await CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ throw CreateTimelineNotExistException(timelineId);
- if (!await _userService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
+ await _userService.ThrowIfUserNotExist(userId);
if (await _database.TimelineMembers.AnyAsync(m => m.TimelineId == timelineId && m.UserId == userId))
return false;
@@ -153,10 +159,9 @@ namespace Timeline.Services.Timeline
public async Task<bool> RemoveMemberAsync(long timelineId, long userId)
{
if (!await CheckTimelineExistenceAsync(timelineId))
- throw new TimelineNotExistException(timelineId);
+ throw CreateTimelineNotExistException(timelineId);
- if (!await _userService.CheckUserExistenceAsync(userId))
- throw new UserNotExistException(userId);
+ await _userService.ThrowIfUserNotExist(userId);
var entity = await _database.TimelineMembers.SingleOrDefaultAsync(m => m.TimelineId == timelineId && m.UserId == userId);
if (entity is null) return false;
@@ -177,7 +182,7 @@ namespace Timeline.Services.Timeline
var entity = await _database.Timelines.Where(t => t.Id == timelineId).Select(t => new { t.OwnerId }).SingleOrDefaultAsync();
if (entity is null)
- throw new TimelineNotExistException(timelineId);
+ throw CreateTimelineNotExistException(timelineId);
return entity.OwnerId == userId;
}
@@ -187,7 +192,7 @@ namespace Timeline.Services.Timeline
var entity = await _database.Timelines.Where(t => t.Id == timelineId).Select(t => new { t.Visibility }).SingleOrDefaultAsync();
if (entity is null)
- throw new TimelineNotExistException(timelineId);
+ throw CreateTimelineNotExistException(timelineId);
if (entity.Visibility == TimelineVisibility.Public)
return true;
@@ -211,7 +216,7 @@ namespace Timeline.Services.Timeline
var entity = await _database.Timelines.Where(t => t.Id == timelineId).Select(t => new { t.OwnerId }).SingleOrDefaultAsync();
if (entity is null)
- throw new TimelineNotExistException(timelineId);
+ throw CreateTimelineNotExistException(timelineId);
if (userId == entity.OwnerId)
return true;
@@ -266,7 +271,7 @@ namespace Timeline.Services.Timeline
var conflict = await _database.Timelines.AnyAsync(t => t.Name == name);
if (conflict)
- throw new TimelineAlreadyExistException();
+ throw CreateTimelineConflictException(name);
var entity = CreateNewTimelineEntity(name, owner);
@@ -282,7 +287,7 @@ namespace Timeline.Services.Timeline
var entity = await _database.Timelines.Where(t => t.Id == id).SingleOrDefaultAsync();
if (entity is null)
- throw new TimelineNotExistException(id);
+ throw CreateTimelineNotExistException(id);
_database.Timelines.Remove(entity);
await _database.SaveChangesAsync();
diff --git a/BackEnd/Timeline/Services/Token/IUserTokenManager.cs b/BackEnd/Timeline/Services/Token/IUserTokenManager.cs
index bdc1add3..39009d69 100644
--- a/BackEnd/Timeline/Services/Token/IUserTokenManager.cs
+++ b/BackEnd/Timeline/Services/Token/IUserTokenManager.cs
@@ -16,7 +16,7 @@ namespace Timeline.Services.Token
/// <returns>The created token and the user info.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> or <paramref name="password"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="username"/> is of bad format.</exception>
- /// <exception cref="UserNotExistException">Thrown when the user with <paramref name="username"/> does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the user with <paramref name="username"/> does not exist.</exception>
/// <exception cref="BadPasswordException">Thrown when <paramref name="password"/> is wrong.</exception>
public Task<UserTokenCreateResult> CreateTokenAsync(string username, string password, DateTime? expireAt = null);
diff --git a/BackEnd/Timeline/Services/Token/UserTokenManager.cs b/BackEnd/Timeline/Services/Token/UserTokenManager.cs
index 5aa85a5e..7ccdfe0a 100644
--- a/BackEnd/Timeline/Services/Token/UserTokenManager.cs
+++ b/BackEnd/Timeline/Services/Token/UserTokenManager.cs
@@ -91,7 +91,7 @@ namespace Timeline.Services.Token
return user;
}
- catch (UserNotExistException e)
+ catch (EntityNotExistException e)
{
var exception = new UserTokenUserNotExistException(token, e);
_logger.LogInformation(exception, Resource.LogTokenVerifiedFail);
diff --git a/BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs b/BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs
index 7ec855aa..92f2429c 100644
--- a/BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs
+++ b/BackEnd/Timeline/Services/User/Avatar/IUserAvatarService.cs
@@ -13,7 +13,7 @@ namespace Timeline.Services.User.Avatar
/// </summary>
/// <param name="userId">User id.</param>
/// <returns>The avatar digest.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
Task<ICacheableDataDigest> GetAvatarDigestAsync(long userId);
/// <summary>
@@ -21,7 +21,7 @@ namespace Timeline.Services.User.Avatar
/// </summary>
/// <param name="userId">User id.</param>
/// <returns>The avatar.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
Task<ByteData> GetAvatarAsync(long userId);
/// <summary>
@@ -31,7 +31,7 @@ namespace Timeline.Services.User.Avatar
/// <param name="avatar">The new avatar data.</param>
/// <returns>The digest of the avatar.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="avatar"/> is null.</exception>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
/// <exception cref="ImageException">Thrown if avatar is of bad format.</exception>
Task<ICacheableDataDigest> SetAvatarAsync(long userId, ByteData avatar);
@@ -39,7 +39,7 @@ namespace Timeline.Services.User.Avatar
/// Remove avatar of a user.
/// </summary>
/// <param name="userId">User id.</param>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
Task DeleteAvatarAsync(long userId);
}
}
diff --git a/BackEnd/Timeline/Services/User/BasicUserService.cs b/BackEnd/Timeline/Services/User/BasicUserService.cs
index 1f1b25f5..0ee8dabd 100644
--- a/BackEnd/Timeline/Services/User/BasicUserService.cs
+++ b/BackEnd/Timeline/Services/User/BasicUserService.cs
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
@@ -18,6 +19,18 @@ namespace Timeline.Services.User
_database = database;
}
+ protected static EntityNotExistException CreateUserNotExistException(string username)
+ {
+ return new EntityNotExistException(EntityTypes.User,
+ new Dictionary<string, object> { ["username"] = username });
+ }
+
+ protected static EntityNotExistException CreateUserNotExistException(long id)
+ {
+ return new EntityNotExistException(EntityTypes.User,
+ new Dictionary<string, object> { ["id"] = id });
+ }
+
public async Task<bool> CheckUserExistenceAsync(long id)
{
return await _database.Users.AnyAsync(u => u.Id == id);
@@ -34,7 +47,7 @@ namespace Timeline.Services.User
var entity = await _database.Users.Where(user => user.Username == username).Select(u => new { u.Id }).SingleOrDefaultAsync();
if (entity == null)
- throw new UserNotExistException(username);
+ throw CreateUserNotExistException(username);
return entity.Id;
}
@@ -44,20 +57,9 @@ namespace Timeline.Services.User
var entity = await _database.Users.Where(u => u.Id == userId).Select(u => new { u.UsernameChangeTime }).SingleOrDefaultAsync();
if (entity is null)
- throw new UserNotExistException(userId);
+ throw CreateUserNotExistException(userId);
return entity.UsernameChangeTime;
}
}
-
- public static class BasicUserServiceExtensions
- {
- public static async Task ThrowIfUserNotExist(this IBasicUserService service, long userId)
- {
- if (!await service.CheckUserExistenceAsync(userId))
- {
- throw new UserNotExistException(userId);
- }
- }
- }
}
diff --git a/BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs b/BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs
new file mode 100644
index 00000000..8a05f452
--- /dev/null
+++ b/BackEnd/Timeline/Services/User/BasicUserServiceExtensions.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Timeline.Services.User
+{
+ public static class BasicUserServiceExtensions
+ {
+ public static async Task ThrowIfUserNotExist(this IBasicUserService service, long userId)
+ {
+ if (!await service.CheckUserExistenceAsync(userId))
+ {
+ throw new EntityNotExistException(EntityTypes.User,
+ new Dictionary<string, object> { ["id"] = userId });
+ }
+ }
+ }
+}
diff --git a/BackEnd/Timeline/Services/User/IBasicUserService.cs b/BackEnd/Timeline/Services/User/IBasicUserService.cs
index 0e30d733..0ae3fdff 100644
--- a/BackEnd/Timeline/Services/User/IBasicUserService.cs
+++ b/BackEnd/Timeline/Services/User/IBasicUserService.cs
@@ -22,7 +22,7 @@ namespace Timeline.Services.User
/// <returns>The id of the user.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="username"/> is of bad format.</exception>
- /// <exception cref="UserNotExistException">Thrown when the user with given username does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the user with given username does not exist.</exception>
Task<long> GetUserIdByUsernameAsync(string username);
/// <summary>
@@ -30,7 +30,7 @@ namespace Timeline.Services.User
/// </summary>
/// <param name="userId">User id.</param>
/// <returns>The time.</returns>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
Task<DateTime> GetUsernameLastModifiedTimeAsync(long userId);
}
}
diff --git a/BackEnd/Timeline/Services/User/IUserPermissionService.cs b/BackEnd/Timeline/Services/User/IUserPermissionService.cs
index 7ff1275b..985a67f5 100644
--- a/BackEnd/Timeline/Services/User/IUserPermissionService.cs
+++ b/BackEnd/Timeline/Services/User/IUserPermissionService.cs
@@ -10,7 +10,7 @@ namespace Timeline.Services.User
/// <param name="userId">The id of the user.</param>
/// <param name="checkUserExistence">Whether check the user's existence.</param>
/// <returns>The permission list.</returns>
- /// <exception cref="UserNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
Task<UserPermissions> GetPermissionsOfUserAsync(long userId, bool checkUserExistence = true);
/// <summary>
@@ -18,7 +18,7 @@ namespace Timeline.Services.User
/// </summary>
/// <param name="userId">The id of the user.</param>
/// <param name="permission">The new permission.</param>
- /// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user does not exist.</exception>
/// <exception cref="InvalidOperationOnRootUserException">Thrown when change root user's permission.</exception>
Task AddPermissionToUserAsync(long userId, UserPermission permission);
@@ -28,7 +28,7 @@ namespace Timeline.Services.User
/// <param name="userId">The id of the user.</param>
/// <param name="permission">The permission.</param>
/// <param name="checkUserExistence">Whether check the user's existence.</param>
- /// <exception cref="UserNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
/// <exception cref="InvalidOperationOnRootUserException">Thrown when change root user's permission.</exception>
Task RemovePermissionFromUserAsync(long userId, UserPermission permission, bool checkUserExistence = true);
}
diff --git a/BackEnd/Timeline/Services/User/IUserService.cs b/BackEnd/Timeline/Services/User/IUserService.cs
index 06155c55..745bd524 100644
--- a/BackEnd/Timeline/Services/User/IUserService.cs
+++ b/BackEnd/Timeline/Services/User/IUserService.cs
@@ -12,7 +12,7 @@ namespace Timeline.Services.User
/// </summary>
/// <param name="id">The id of the user.</param>
/// <returns>The user info.</returns>
- /// <exception cref="UserNotExistException">Thrown when the user with given id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the user with given id does not exist.</exception>
Task<UserEntity> GetUserAsync(long id);
/// <summary>
@@ -38,7 +38,7 @@ namespace Timeline.Services.User
/// <param name="param">The new information.</param>
/// <returns>The new user info.</returns>
/// <exception cref="ArgumentException">Thrown when some fields in <paramref name="param"/> is bad.</exception>
- /// <exception cref="UserNotExistException">Thrown when user with given id does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when user with given id does not exist.</exception>
/// <remarks>
/// Version will increase if password is changed.
/// </remarks>
@@ -52,7 +52,7 @@ namespace Timeline.Services.User
/// <returns>User id.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="username"/> or <paramref name="password"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="username"/> is of bad format or <paramref name="password"/> is empty.</exception>
- /// <exception cref="UserNotExistException">Thrown when the user with given username does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown when the user with given username does not exist.</exception>
/// <exception cref="BadPasswordException">Thrown when password is wrong.</exception>
Task<long> VerifyCredential(string username, string password);
@@ -64,7 +64,7 @@ namespace Timeline.Services.User
/// <param name="newPassword">New password.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="oldPassword"/> or <paramref name="newPassword"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="oldPassword"/> or <paramref name="newPassword"/> is empty.</exception>
- /// <exception cref="UserNotExistException">Thrown if the user with given username does not exist.</exception>
+ /// <exception cref="EntityNotExistException">Thrown if the user with given username does not exist.</exception>
/// <exception cref="BadPasswordException">Thrown if the old password is wrong.</exception>
Task ChangePassword(long id, string oldPassword, string newPassword);
}
diff --git a/BackEnd/Timeline/Services/User/UserAlreadyExistException.cs b/BackEnd/Timeline/Services/User/UserAlreadyExistException.cs
deleted file mode 100644
index e257af74..00000000
--- a/BackEnd/Timeline/Services/User/UserAlreadyExistException.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-
-namespace Timeline.Services.User
-{
- /// <summary>
- /// The user requested does not exist.
- /// </summary>
- [Serializable]
- public class UserAlreadyExistException : EntityAlreadyExistException
- {
- public UserAlreadyExistException() : this(null, null, null) { }
- public UserAlreadyExistException(object? entity) : this(entity, null, null) { }
- public UserAlreadyExistException(object? entity, Exception? inner) : this(entity, null, inner) { }
- public UserAlreadyExistException(object? entity, string? message, Exception? inner)
- : base(EntityNames.User, entity, message ?? Resource.ExceptionUserAlreadyExist, inner)
- {
-
- }
-
- protected UserAlreadyExistException(
- System.Runtime.Serialization.SerializationInfo info,
- System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
-}
diff --git a/BackEnd/Timeline/Services/User/UserNotExistException.cs b/BackEnd/Timeline/Services/User/UserNotExistException.cs
deleted file mode 100644
index bc5d8d9e..00000000
--- a/BackEnd/Timeline/Services/User/UserNotExistException.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-
-namespace Timeline.Services.User
-{
- /// <summary>
- /// The user requested does not exist.
- /// </summary>
- [Serializable]
- public class UserNotExistException : EntityNotExistException
- {
- public UserNotExistException() : this(null, null, null, null) { }
- public UserNotExistException(string? username) : this(username, null, null, null) { }
- public UserNotExistException(string? username, Exception? inner) : this(username, null, null, inner) { }
- public UserNotExistException(long id) : this(null, id, null, null) { }
- public UserNotExistException(long id, Exception? inner) : this(null, id, null, inner) { }
- public UserNotExistException(string? username, long? id, string? message, Exception? inner)
- : base(EntityNames.User, message ?? Resource.ExceptionUserNotExist, inner)
- {
- Username = username;
- Id = id;
- }
-
- protected UserNotExistException(
- System.Runtime.Serialization.SerializationInfo info,
- System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
-
- /// <summary>
- /// The username of the user that does not exist.
- /// </summary>
- public string? Username { get; set; }
-
- /// <summary>
- /// The id of the user that does not exist.
- /// </summary>
- public long? Id { get; set; }
- }
-}
diff --git a/BackEnd/Timeline/Services/User/UserPermissionService.cs b/BackEnd/Timeline/Services/User/UserPermissionService.cs
index f9911c7f..f6f11c61 100644
--- a/BackEnd/Timeline/Services/User/UserPermissionService.cs
+++ b/BackEnd/Timeline/Services/User/UserPermissionService.cs
@@ -8,21 +8,19 @@ namespace Timeline.Services.User
public class UserPermissionService : IUserPermissionService
{
private readonly DatabaseContext _database;
+ private readonly IBasicUserService _basicUserService;
- public UserPermissionService(DatabaseContext database)
+ public UserPermissionService(DatabaseContext database, IBasicUserService basicUserService)
{
_database = database;
+ _basicUserService = basicUserService;
}
private async Task CheckUserExistence(long userId, bool checkUserExistence)
{
if (checkUserExistence)
{
- var existence = await _database.Users.AnyAsync(u => u.Id == userId);
- if (!existence)
- {
- throw new UserNotExistException(userId);
- }
+ await _basicUserService.ThrowIfUserNotExist(userId);
}
}
diff --git a/BackEnd/Timeline/Services/User/UserService.cs b/BackEnd/Timeline/Services/User/UserService.cs
index 443afb90..a47bc860 100644
--- a/BackEnd/Timeline/Services/User/UserService.cs
+++ b/BackEnd/Timeline/Services/User/UserService.cs
@@ -54,9 +54,10 @@ namespace Timeline.Services.User
}
}
- private static void ThrowUsernameConflict(object? user)
+ private static EntityAlreadyExistException CreateUsernameConflictException(string username)
{
- throw new UserAlreadyExistException(user);
+ throw new EntityAlreadyExistException(EntityTypes.User,
+ new Dictionary<string, object> { ["username"] = username });
}
public async Task<UserEntity> GetUserAsync(long id)
@@ -64,7 +65,7 @@ namespace Timeline.Services.User
var user = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
if (user is null)
- throw new UserNotExistException(id);
+ throw CreateUserNotExistException(id);
return user;
}
@@ -89,7 +90,7 @@ namespace Timeline.Services.User
var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == param.Username);
if (conflict)
- ThrowUsernameConflict(null);
+ throw CreateUsernameConflictException(param.Username);
var newEntity = new UserEntity
{
@@ -120,8 +121,8 @@ namespace Timeline.Services.User
}
var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
- if (entity == null)
- throw new UserNotExistException(id);
+ if (entity is null)
+ throw CreateUserNotExistException(id);
if (param is not null)
{
@@ -133,7 +134,7 @@ namespace Timeline.Services.User
{
var conflict = await _databaseContext.Users.AnyAsync(u => u.Username == username);
if (conflict)
- ThrowUsernameConflict(null);
+ throw CreateUsernameConflictException(username);
entity.Username = username;
entity.UsernameChangeTime = now;
@@ -180,7 +181,7 @@ namespace Timeline.Services.User
if (entity is null)
{
_logger.LogInformation(Resource.LogVerifyCredentialsUsernameBad, username);
- throw new UserNotExistException(username);
+ throw CreateUserNotExistException(username);
}
if (!_passwordService.VerifyPassword(entity.Password, password))
@@ -204,7 +205,7 @@ namespace Timeline.Services.User
var entity = await _databaseContext.Users.Where(u => u.Id == id).SingleOrDefaultAsync();
if (entity is null)
- throw new UserNotExistException(id);
+ throw CreateUserNotExistException(id);
if (!_passwordService.VerifyPassword(entity.Password, oldPassword))
throw new BadPasswordException(oldPassword);
diff --git a/BackEnd/Timeline/Startup.cs b/BackEnd/Timeline/Startup.cs
index 994dd7bf..812bf317 100644
--- a/BackEnd/Timeline/Startup.cs
+++ b/BackEnd/Timeline/Startup.cs
@@ -12,8 +12,10 @@ using System.Text.Json.Serialization;
using Timeline.Auth;
using Timeline.Configs;
using Timeline.Entities;
+using Timeline.Filters;
using Timeline.Formatters;
using Timeline.Helpers;
+using Timeline.Models;
using Timeline.Models.Converters;
using Timeline.Routes;
using Timeline.Services;
@@ -66,8 +68,10 @@ namespace Timeline
{
setup.InputFormatters.Add(new StringInputFormatter());
setup.InputFormatters.Add(new ByteDataInputFormatter());
- setup.Filters.Add(new ConsumesAttribute(MediaTypeNames.Application.Json, "text/json"));
- setup.Filters.Add(new ProducesAttribute(MediaTypeNames.Application.Json, "text/json"));
+ setup.Filters.Add(new ConsumesAttribute(MimeTypes.ApplicationJson, MimeTypes.TextJson));
+ setup.Filters.Add(new ProducesAttribute(MimeTypes.ApplicationJson, MimeTypes.TextJson));
+ setup.Filters.Add<CatchEntityNotExistExceptionFilter>();
+ setup.Filters.Add<CatchEntityAlreadyExistExceptionFilter>();
setup.UseApiRoutePrefix("api");
})
.AddJsonOptions(options =>
diff --git a/BackEnd/Timeline/Timeline.csproj b/BackEnd/Timeline/Timeline.csproj
index ace1aab5..b151d123 100644
--- a/BackEnd/Timeline/Timeline.csproj
+++ b/BackEnd/Timeline/Timeline.csproj
@@ -58,6 +58,11 @@
<AutoGen>True</AutoGen>
<DependentUpon>Resource.resx</DependentUpon>
</Compile>
+ <Compile Update="Filters\Resource.Designer.cs">
+ <DesignTime>True</DesignTime>
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resource.resx</DependentUpon>
+ </Compile>
<Compile Update="Resources\Entities.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
@@ -159,6 +164,10 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
</EmbeddedResource>
+ <EmbeddedResource Update="Filters\Resource.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resource.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
<EmbeddedResource Update="Resources\Entities.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Entities.Designer.cs</LastGenOutput>