但仅限于我们的生产服务器。适用于其他所有环境。 Web服务在生产上运行得很好,我不明白什么(显然)破坏了我在生产中抛出的异常。
首先,jquery。选中复选框后,我们会调用Web服务尝试执行所谓的“令牌分配”:
if (chk.is(":checked")) {
chk.invoke('AssignToken',
params,
function () {
//Go up the tree to the category, then down into the header to find the count.
var spnTokenCount = $this.closest('.category').find('.tokenCount');
var tokenCount = 1;
if (!isNaN(spnTokenCount.text())) {
tokenCount = parseInt(spnTokenCount.text());
tokenCount--;
spnTokenCount.text(tokenCount.toString());
}
if (tokenCount == 0) {
$this.closest('.category').find('.spnAvailable').hide();
$this.closest('.category').find('.spnPurchase').show();
//Let's find the unchecked elements and not allow them to be selected.
$this.closest('table').find('.tokenAssignment').find('input:checkbox').each(function (index, element) {
if (!element.checked) {
element.disabled = true;
}
});
}
},
function (xhr, textStatus, error) {
chk.attr('checked', false);
var response = '';
eval('response = ' + xhr.responseText);
if (response.ExceptionType == 'xxx.TokenAssignmentException') {
alert('Token assignment failed, you may be out of tokens.');
} else {
alert('Token assignment error.');
//alert('Token unassignment failed\n\n' + response.ExceptionType + '\n' + response.Message + ':\n' + response.StackTrace);
}
}
);
在我的基页中,我有以下WebMethod:
[WebMethod]
public static void AssignToken(int accountId, int courseId, int studentId, string studentType, Guid userId)
{
try
{
CourseToken ct = CourseTokenFactory.AssignToken(accountId, courseId, studentId, studentType, userId);
if (ct == null)
{
Logger.Error("Token assignment attempt failed for " +
accountId.ToString() +
", course " + courseId.ToString() + ", student " + studentId.ToString() +
" of type " + studentType);
throw new TokenAssignmentException("Token assignment attempt failed.");
}
}
catch (Exception ex)
{
Logger.Error("Failed trying to assign token for account " +
accountId.ToString() + ", course " + courseId.ToString() +
", student " + studentId.ToString() + " of type " + studentType, ex);
throw;
}
}
我们看到两条日志消息都已写入,因此Web服务正常运行(在这种情况下。从工厂返回一个null的CourseToken意味着我们找不到可用的日志消息)。
正如你在jquery错误处理方法中看到的那样,我检查响应的ExceptionType,看看我在这种情况下抛出的异常类型,并给出更友好的错误。
但是,在生产时,xhr.responseText变为“处理请求时出错”,ExceptionType为空字符串。在所有其他环境中,xhr.responseText是我们所期望的,ExceptionType是完全限定的类名(匿名化为'xxx'),我们得到更友好的错误消息。
我不确定如何进一步调试。我已经通过我们正在创建的日志消息验证并抛出了我们期望的异常类型,并且使用了firebug,当它返回到客户端时它不在xhr对象中。 (但只在一个环境中)。
或者这是该方法的一个更基本的问题?也许,WebMethod应该返回布尔值,或者已经分配的CourseToken,或者某些东西(false / null表示非赋值)而不是特定的异常类型?
答案 0 :(得分:0)
我不是100%肯定这是答案,但我讨厌我不能在回复编辑器中写段落。
我不能相信,我的产品经理(喜欢讨厌的人)发现了这一点:https://connect.microsoft.com/VisualStudio/feedback/details/290881/exceptions-thrown-from-webmethods-are-swallowed-by-resthandler-when-httpcontext-iscustomerrorenabled-true
不同之处在于,我们在生产Web服务器上将customErrors设置为RemoteOnly,因此在该环境中吞下了从Web服务中抛出的异常。
我对这就是答案非常有信心;我们在网络服务器上进行了RDP,在那里启动了一个浏览器,并使用我们从服务器外部的浏览器进行测试的完全相同的模拟账户来点击生产应用程序。
得到了友好的' message,这意味着xhr对象保留了Web方法抛出的ExceptionType,因为我们在本地没有自定义错误。
所以我想这里的教训不是使用异常来处理这种情况。我必须重写服务和两个ajax好/错误方法。使web方法发送回bool或object / null或其他内容以指示赋值是否有效,并在错误处理程序中处理真正的异常。