如何在 Dart 中从服务器 API 代码中抛出异常?
How to throw an exception from a server API code in Dart?
我正在用 Dart 开发客户端-服务器应用程序,并且一直在关注 tutorial。我的服务器代码大致是基于它。
在我的服务器API代码中,当出错的时候,我想抛出一个异常,例如:
void checkEverything() {
if(somethingWrong)
throw new RpcError(400, "Something Wrong", "Something went wrong!");
}
@ApiMethod(path: 'myservice/{arg}')
Future<String> myservice(String arg) async {
checkEverything();
// ...
return myServiceResponse;
}
并且该异常应该在主服务器中处理,例如
// ...
var apiResponse;
try {
var apiRequest = new HttpApiRequest.fromHttpRequest(request);
apiResponse = await _apiServer.handleHttpApiRequest(apiRequest);
} catch (error, stack) {
var exception = error is Error ? new Exception(error.toString()) : error;
if((error is RpcError && error.statusCode==400) {
// My code for creating the HTTP response
apiResponse = new HttpApiResponse.error(
HttpStatus.BAD_REQUEST, "Something went wrong", exception, stack);
}
else {
// standard error processing from the Dart tutorial
apiResponse = new HttpApiResponse.error(
HttpStatus.INTERNAL_SERVER_ERROR, exception.toString(),
exception, stack);
}
}
(片段,请参阅 tutorial 了解完整代码,但没有我的错误处理)。
但是,我的异常从来没有达到上面的catch
子句。相反,它似乎陷入了 _apiServer.handleHttpApiRequest(apiRequest);
,而后者又抛出了 INTERNAL_SERVER_ERROR (500):
[WARNING] rpc: Method myservice returned null instead of valid return value
[WARNING] rpc:
Response
Status Code: 500
Headers:
access-control-allow-credentials: true
access-control-allow-origin: *
cache-control: no-cache, no-store, must-revalidate
content-type: application/json; charset=utf-8
expires: 0
pragma: no-cache
Exception:
RPC Error with status: 500 and message: Method with non-void return type returned 'null'
Unhandled exception:
RPC Error with status: 400 and message: Something went wrong!
#0 MyApi.myservice (package:mypackage/server/myapi.dart:204:24)
[...]
这对客户来说不是很具体。我想传达发生了错误,而不是 return 一个好看的回应。那么在 Dart 中处理服务器端异常并将该信息传递给客户端的正确方法是什么?
好的,我想我解决了问题。 throw
子句显然必须在 API 方法本身中,而不是在从属方法中。即:
@ApiMethod(path: 'myservice/{arg}')
Future<String> myservice(String arg) async {
if(somethingWrong)
throw new RpcError(400, "Something Wrong", "Something went wrong!");
// ...
return myServiceResponse;
}
而不是:
void checkEverything() {
if(somethingWrong)
throw new RpcError(400, "Something Wrong", "Something went wrong!");
}
@ApiMethod(path: 'myservice/{arg}')
Future<String> myservice(String arg) async {
checkEverything();
// ...
return myServiceResponse;
}
我正在用 Dart 开发客户端-服务器应用程序,并且一直在关注 tutorial。我的服务器代码大致是基于它。
在我的服务器API代码中,当出错的时候,我想抛出一个异常,例如:
void checkEverything() {
if(somethingWrong)
throw new RpcError(400, "Something Wrong", "Something went wrong!");
}
@ApiMethod(path: 'myservice/{arg}')
Future<String> myservice(String arg) async {
checkEverything();
// ...
return myServiceResponse;
}
并且该异常应该在主服务器中处理,例如
// ...
var apiResponse;
try {
var apiRequest = new HttpApiRequest.fromHttpRequest(request);
apiResponse = await _apiServer.handleHttpApiRequest(apiRequest);
} catch (error, stack) {
var exception = error is Error ? new Exception(error.toString()) : error;
if((error is RpcError && error.statusCode==400) {
// My code for creating the HTTP response
apiResponse = new HttpApiResponse.error(
HttpStatus.BAD_REQUEST, "Something went wrong", exception, stack);
}
else {
// standard error processing from the Dart tutorial
apiResponse = new HttpApiResponse.error(
HttpStatus.INTERNAL_SERVER_ERROR, exception.toString(),
exception, stack);
}
}
(片段,请参阅 tutorial 了解完整代码,但没有我的错误处理)。
但是,我的异常从来没有达到上面的catch
子句。相反,它似乎陷入了 _apiServer.handleHttpApiRequest(apiRequest);
,而后者又抛出了 INTERNAL_SERVER_ERROR (500):
[WARNING] rpc: Method myservice returned null instead of valid return value
[WARNING] rpc:
Response
Status Code: 500
Headers:
access-control-allow-credentials: true
access-control-allow-origin: *
cache-control: no-cache, no-store, must-revalidate
content-type: application/json; charset=utf-8
expires: 0
pragma: no-cache
Exception:
RPC Error with status: 500 and message: Method with non-void return type returned 'null'
Unhandled exception:
RPC Error with status: 400 and message: Something went wrong!
#0 MyApi.myservice (package:mypackage/server/myapi.dart:204:24)
[...]
这对客户来说不是很具体。我想传达发生了错误,而不是 return 一个好看的回应。那么在 Dart 中处理服务器端异常并将该信息传递给客户端的正确方法是什么?
好的,我想我解决了问题。 throw
子句显然必须在 API 方法本身中,而不是在从属方法中。即:
@ApiMethod(path: 'myservice/{arg}')
Future<String> myservice(String arg) async {
if(somethingWrong)
throw new RpcError(400, "Something Wrong", "Something went wrong!");
// ...
return myServiceResponse;
}
而不是:
void checkEverything() {
if(somethingWrong)
throw new RpcError(400, "Something Wrong", "Something went wrong!");
}
@ApiMethod(path: 'myservice/{arg}')
Future<String> myservice(String arg) async {
checkEverything();
// ...
return myServiceResponse;
}