2015-02-11 26 views
-2

我正在使用Azure,我有简单的尝试catch块 我现在正在做的是当我们有任何错误,我会通过电子邮件发送错误消息,现在我想检测瞬态错误,只是忽略发送电子邮件在C#异常处理有没有办法来检测瞬态错误?

private void SomeMethod() 
{ 
    try 
    { 
     // Do stuff 
    } 
    catch (Exception ex) 
    {   
     HandleError(ex); 
     return RedirectToAction("Index", "Error"); 
    } 
} 

protected void HandleError(Exception ex) 
{ 
     //and here i want to check if the cause of exception is not a transient  error then write a code to email the error details 
} 
+0

你能发布你的代码? – 2015-02-11 17:04:30

+4

以及您如何确定瞬态错误是什么? – Kritner 2015-02-11 17:04:40

+0

写在MSDN https://msdn.microsoft.com/en-us/library/hh680934(v=pandp.50).aspx瞬态错误是:瞬态故障是由于某些临时状态,例如网络中发生的错误连接问题或服务不可用性 – user4092086 2015-02-11 18:16:08

回答

0

基于链接,您刚刚发布,代码样本提供:

// Define your retry strategy: retry 3 times, 1 second apart. 
var retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(1)); 

// Define your retry policy using the retry strategy and the Azure storage 
// transient fault detection strategy. 
var retryPolicy = 
    new RetryPolicy<StorageTransientErrorDetectionStrategy>(retryStrategy); 

// Do some work that may result in a transient fault. 
try 
{ 
    // Call a method that uses Azure storage and which may 
    // throw a transient exception. 
    retryPolicy.ExecuteAction(
    () => 
    { 
     this.queue.CreateIfNotExist(); 
    }); 
} 
catch (Exception) 
{ 
    // All of the retries failed. 
} 

根据该文件的例外则不会引发直到它不再是一个暂时的错误所界定的重试策略。实际上 - 利用瞬态故障处理应用程序块已经在做你在问你的问题了。重试会无提示地重试(无一例外),直到出现异常的时间点 - 发生重试超过重试策略时。

以下不应被视为“好码”,它只不过是在TFHAB 可能如何确定传输错误的例子。

private void DoStuff() 
{ 
    try 
    { 
     this.DoSomethingThatCouldPotentiallyCauseTransientErrors(5); 
    } 
    catch (Exception ex) 
    { 
     // This would not be caught until the "retries" have occurred. 
     this.HandleException(ex); 
     return RedirectToAction("Index", "Error"); 
    } 
} 

private void DoSomethingThatCouldPotentiallyCauseTransientErrors(int retryAttemptsBeforeExceptionThrown) 
{ 
    // Note that this will *always throw an exception*, 
    // I'm (attempting to) simply demonstrate my point of how the transient errors could be defined. 

    for (int i = 0; i < retryAttemptsBeforeExceptionThrown) 
    { 
     try  
     { 
      int x = 0; 
      int y = 0; 

      int result = x/y; 
     } 
     catch (Exception) 
     { 
      if (i < retryAttemptsBeforeExceptionThrown-1) 
      { 
       // Swallow/ignore the exception, and retry 
       // Note that anything hitting this block would be considered a "transient error", 
       // as we are not raising an exception 
      } 
      else 
      { 
       // Too many failed attempts have occurred, ***now*** we raise an exception to the caller 
       throw; 
      } 
     } 
    } 
} 

private void HandleException(Exception ex) 
{ 
    // Implementation 
} 

希望诸如此类的回答约翰的问题上是什么让一个“暂时性错误”

+0

但如果我不想使用和安装瞬态故障处理应用程序块是否有任何方法来检测和异常类的其他错误检测和分离瞬态错误?其实我不想在短暂错误的情况下重试,只是我想忽略在这种情况下发送电子邮件 – user4092086 2015-02-11 18:40:36

+0

但是......根据您的重试策略,***定义了短暂错误***。如果您没有使用“瞬态故障处理应用程序块”,那么错误不是暂时的,它们只是例外。 – Kritner 2015-02-11 18:43:53

+0

所以没有标志或错误号码,从他们我们可以检测到异常的原因是一个瞬态错误? – user4092086 2015-02-11 18:50:12

0

可以使用的信号从我的Apache许可证Griffin.Framework

public class YourController 
{ 
    static Signal _errorsignal = Signal.Create("YourController.Error"); 

    public ActionResult SomeAction() 
    { 
     try 
     { 
      //some logic 

      //logic succeeded, reset 
      _errorSignal.Reset(); 
     } 
     catch (Exception ex) 
     { 
      //Raised for the first time, notify 
      if (_errorSignal.Raise(ex)) 
       HandleError(ex); 
      return RedirectToAction("Index", "Error"); 
     } 

    //[...] 
} 

它跟踪上下文并且还可以将状态更改(从所有信号)上载到HTTP服务器。

而是在每个控制器具有的HandleError,你也可以把你的Global.asax以下几点:

//put in the Init method 
Signal.SignalRaised += OnGlobalHandling; 

public void OnGlobalHandling(object sender, SignalRaisedEventArgs e) 
{ 
    var signal = (Signal)sender; 
    //send email 
} 
+0

在你的框架中,瞬态错误和“非瞬态”错误有什么区别? – 2015-02-11 19:08:10

1

如果您正在使用Azure的客户端SDK(最新的版本> = v4.3.0.0) ,默认重试策略是Exponential Retry。即使您没有专门定义任何重试策略,情况也是如此。客户端SDK指数重试策略具有根据从Azure存储服务响应返回的HttpStatusCode几乎检测到瞬时错误的逻辑。所有这些重试都将在您向代码透明地完成,当您向Azure存储发出请求并且该请求失败时,客户端sdk认为这是一个瞬态(几乎所有5xx Http状态代码)。

如果你想停止客户端SDK完全重试并在catch块中完全控制它,那么你可以传递NoRetry策略作为[Table/Blob/Queue] RequestOptions的一部分来重试由客户端SDK完成引擎盖下的操作。

然后,在您的catch块中,您需要捕获客户端SDK在失败的请求中抛出的StorageException,解析嵌入其中的HttpStatusCode,根据错误是否是暂时的,相应的行动。

当然,并非所有的异常都是StorageException,你也可能会得到像null ref这样的非存储异常,你也可以对这些进行相同的处理,它们通常不会是暂时的。

如果你想要去的路线,你应该知道你在做什么,有什么实际的客户端SDK是做在自己短暂的错误检测和重试机制,并彻底关闭它的影响。我见过很多情况下,人们Azure存储RetryPolicies拨弄没有完全了解它做什么,并最终超载这是已经由客户端SDK或导致更多的等待时间重试不必要的重试服务,降低产量等

+0

我目前使用ASB SDK提供的原生重试策略,正如您所提到的那样,它默认使用RetryExponentail重试策略在引擎盖下重试...我有兴趣知道如何知道RetryExponential类的默认参数......另外,您可以共享任何描述底层细节的文档......(我已经看到了这个 - https:// docs。 microsoft.com/en-au/azure/architecture/best-practices/retry-service-specific#azure-event-hubs-retry-guidelines) – gkb 2017-06-13 12:09:57

相关问题