在我的REST API服务层,我有一个类ProductService。
以下逻辑存在于我所有的函数中:执行Validate,如果验证失败则抛出无效异常,如果通过,则继续执行下一个try-catch,如果失败则抛出一般错误:
def addProduct(request:AddProductRequest): BaseResponse[String] =
{
try
{
request.validate
}
catch
{
case ex: Exception => {
Logger.error("Failed to add product, Validation failed", ex);
val errorResponse:ErrorResponse[String] = new ErrorResponseList().InvalidParameters
errorResponse.addMessage(ex.getMessage)
return errorResponse
}
}
try
{
val addedProductId = productRepository.addProduct(request.language, request.tenantId, request.product)
DTOResponse(addedProductId)
}
catch
{
case ex: Exception => {
Logger.error("Failed to add product to tenant Id="+request.tenantId+" language="+request.language, ex);
val errorResponse:ErrorResponse[String] = new ErrorResponseList().GeneralError
errorResponse.addMessage(ex.getMessage())
return errorResponse
}
}
}
现在,不要重复请求。用相同的try和catch对所有函数进行验证,我用以下函数创建了一个基类:
abstract class ServiceBase {
def validate[T](request:BaseRequest)
{
try
{
request.validate
}
catch
{
case ex: Exception => {
Logger.error("Validation failed", ex);
val errorResponse:ErrorResponse[String] = new ErrorResponseList().InvalidParameters
errorResponse.addMessage(ex.getMessage)
return errorResponse
}
}
}
现在,我的addProduct(..)看起来像:
validate(request)
..the rest of the code - the 2nd try-catch
这样可以节省很多行。
问题是,如果验证失败,它将永远不会返回。我在ServiceBase中得到以下错误:
Multiple markers at this line
- enclosing method validate has result type Unit: return value discarded
- enclosing method validate has result type Unit: return value discarded
- a pure expression does nothing in statement position; you may be omitting necessary
parentheses
validate
没有返回类型(因此默认返回Unit
),在ServiceBase
中,您对validate
的签名应该是这样的:
def validate[T](request:BaseRequest): BaseResponse[String] =
(假设您想返回一个BaseResponse[String]
)
这可能对某人有用,有一天,函数式编程。我们是不是说了^_^
将ServiceBase validate更改为:
def validate[T](request:BaseRequest):Option[BaseResponse[T]] =
{
try
{
request.validate
None
}
catch
{
case ex: Exception => {
Logger.error("Validation failed", ex);
val errorResponse:ErrorResponse[T] = new ErrorResponseList().InvalidParameters
errorResponse.addMessage(ex.getMessage)
return Some(errorResponse)
}
}
}
现在我知道了:
def getProducts(request:GetProductsRequest) :BaseResponse[ProductSearchResults] =
{
validate[ProductSearchResults](request).getOrElse(
{
try
{
val products = productRepository.getProducts(request.language,request.tenantId,request.productIds)
val foundProducts = for (product <- products) yield (product.id)
val notFoundProducts = request.productIds filterNot (foundProducts.toSet)
val responseWrapper = new ProductSearchResults(products, notFoundProducts)
DTOResponse(responseWrapper)
}
catch
{
case ex: Exception => {
Logger.error("Failed to get products from tenant Id="+request.tenantId+" language="+request.language, ex);
val errorResponse:ErrorResponse[ProductSearchResults] = new ErrorResponseList().GeneralError
errorResponse.addMessage(ex.getMessage())
return errorResponse
}
}})
}