Microsoft Graph更新日历事件时ODataError捕获失败,无法创建新事件
解决Microsoft Graph更新日历事件时的404异常捕获问题
问题根源
你当前的代码无法捕获事件不存在的异常,核心原因是Microsoft Graph SDK v5及以上版本不再抛出ServiceException,而是抛出Microsoft.Graph.Models.ODataErrors.ODataError。原来的catch (ServiceException ex)块根本无法命中这个异常,导致直接抛出未处理的错误,无法进入创建新事件的分支。另外你代码里手动赋值ex.ResponseStatusCode = 404是无效操作,完全没必要。
解决方案
- 捕获正确的异常类型:优先捕获
ODataError,而非ServiceException - 精准判断异常场景:通过
ODataError的Error.Code(固定值ErrorItemNotFound)或错误消息来识别事件不存在的情况,用错误码判断比匹配文本更可靠 - 补充创建事件的提交逻辑:原来的代码只实例化了
newEvent对象,但没有调用Graph SDK的创建接口,必须加上提交操作才能生成新事件
修改后的完整代码示例
try { await _graphServiceClient.Me.Calendar.Events[appointment.MicrosoftGraphEventId] .PatchAsync(updatedEvent); _logger.LogInformation("Updated existing Graph event with ID: {EventId}", appointment.MicrosoftGraphEventId); } catch (ODataError oDataEx) { // 优先用错误码判断,兼容不同语言环境的错误消息 bool isEventNotFound = oDataEx.Error?.Code == "ErrorItemNotFound" || oDataEx.Error?.Message.Contains("not found in the store", StringComparison.OrdinalIgnoreCase) == true; if (isEventNotFound) { _logger.LogWarning("Graph event {EventId} was not found. Creating new event.", appointment.MicrosoftGraphEventId); var newEvent = new Event { Subject = subject, Body = new ItemBody { Content = bodyContent, ContentType = BodyType.Text }, Start = new DateTimeTimeZone { DateTime = meetingStartTime.ToString("yyyy-MM-ddTHH:mm:ss"), TimeZone = "South Africa Standard Time" }, End = new DateTimeTimeZone { DateTime = meetingEndTime.ToString("yyyy-MM-ddTHH:mm:ss"), TimeZone = "South Africa Standard Time" }, Location = new Location { DisplayName = graphEventLocation } }; // 提交新事件到Microsoft Graph var createdEvent = await _graphServiceClient.Me.Calendar.Events.PostAsync(newEvent); // 更新本地存储的事件ID为新创建的ID,避免后续再次报错 appointment.MicrosoftGraphEventId = createdEvent.Id; // 这里可以添加保存appointment到数据库的逻辑 } else { // 非事件不存在的错误,重新抛出让上层处理 throw; } } catch (Exception ex) { _logger.LogError(ex, "Unexpected error when handling Graph calendar event"); throw; }
额外说明
- 若你仍在使用Graph SDK v4及以下版本,
ServiceException是正确的捕获类型,但需通过ex.StatusCode获取404状态,而非手动赋值 - 用固定错误码
ErrorItemNotFound判断比匹配错误消息更稳定,因为错误消息可能随SDK版本或本地化语言变化
内容的提问来源于stack exchange,提问作者WorkingProgrammer
相关产品推荐
相关产品推荐

