Cette nuit m'est venu une problèmatique assez délicate.
Dans ma page, je charge plusieurs UserControl indépendants les uns des autres. Si l'un d'entre eux lance une exception il ne faut pas que ca empêche les autres de fonctionner, mais que cela affiche un message d'erreur à l'endroit ou est supposé être ce UserControl.
Or si on lance une exception dans un UserControl, celle ci est directement affiché et arrete l'execution de la page :-(
Je sais qu'un UserControl possede
l'evenement Error qui selon
la documentation "Occurs when an unhandled exception is thrown". Je m'abonne donc à l'evenement Error, lance une exception dans le load du UserControl et l'évenement n'est jamais lancé !!!
Me voila donc à la recherche d'explication. Avant de lancer
Reflector, un petit tour sur
mozbot qui me renvoie vers ce post :
The not so clear Error event il explique en détail comment les erreurs sont gérés au sein d'une page (même pas besoin de lancer Reflector pour le voir de mes propres yeux :)). Tous se joue dans la méthode ProcessRequestMain(boolean, boolean) de l'objet Page (comme de trés nombreuses choses). Je ne vais pas rééxpliquer comment ca fonctionne puisque
Victor Garcia Aprea le fait trés bien dans son post :
The not so clear Error event et la conclusion à retenir est que l'évenement Error d'un UserControl ne sert à rien !
Sachant tout cela me voici à la recherche d'une solution. Ce que je veux c'est quand une exception est lancé dans mon UserControl, cela arrete le fonctionnement de celui ci et c'est tout! malheureusement aprés plusieurs heures de recherche et de test, je n'ai rien trouvé de réellement concluant. La seule solution que j'ai trouvé est de surchargé les méthodes OnEvent et d'entourer tout ca dans un bloc try :
Private lastError As Exception = Nothing
' on fait évidement la meme chose, pour OnInit, OnPrerender, etc...
Protected NotOverridable Overrides Sub OnLoad(ByVal e As System.EventArgs)
Try
If lastError Is Nothing Then
MyBase.OnLoad(e)
End If
Catch ex As Exception
lastError = ex
Me.OnError(e)
End Try
End Sub
Maintenant si une erreur est déclenché dans le load de l'UserControl, je la rattrape et l'evenement Error devient utile :)
Il me reste plus qu'a informer qu'il y a eu une erreur.
Private PlaceHolderError As PlaceHolder
Protected NotOverridable Overrides Sub OnError(ByVal e As System.EventArgs)
' on log
' CSP.Utilities.Logs.WriteLine(TraceLevel.Error, lastError)
MyBase.OnError(e)
End Sub
Protected NotOverridable Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
Try
If lastError Is Nothing Then
MyBase.Render(writer)
ElseIf PlaceHolderError IsNot Nothing Then
PlaceHolderError.RenderControl(writer)
End If
Catch ex As Exception
Me.OnError(EventArgs.Empty)
End Try
End Sub
Le problème est que ces bidouilles n'arretent pas l'execution du UserControl ! :-( en plus on ne recupere pas toutes les erreurs si on fait ca :
Protected Overrides Sub CreateChildControls()
Throw New Exception
MyBase.CreateChildControls()
End Sub
Alors c'est toute la page qui plante :-(
Si quelqu'un a une solution ou juste une idée de solution, je serais ravis de l'entendre :-)