web-dev-qa-db-fra.com

Comment obtenir le numéro de ligne d'erreur du code en utilisant try-catch

Je veux obtenir le numéro de ligne du code qui cause une erreur. Par exemple;

static void Main(string[] args)
{
    using (SqlConnection conn = new SqlConnection(bagcum))
    {
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = "DONTINSERT into GIVEMEERROR(CamNo,Statu) values (" + 23 + "," + 0 + ")";
        conn.Open();
        int n = cmd.ExecuteNonQuery();
    }
}

comme nous savons que le code ne fonctionne pas, il générera une exception. Numéro de ligne du code qui est:

int n = cmd.ExecuteNonQuery();

Alors, comment obtenir ce numéro de ligne en utilisant try-catch? J'ai essayé d'utiliser une classe StackTrace mais elle donne le numéro de ligne égal à 0:

static void Main(string[] args)
{
    try
    {
        using (SqlConnection conn = new SqlConnection(bagcum))
        {
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = "DONTINSERT into GIVEMEERROR(CamNo,Statu) values (" + 23 + "," + 0 + ")";
            conn.Open();
            int n = cmd.ExecuteNonQuery();
        }        
    }
    catch (Exception ex)
    {
        System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);            
        Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
    }
}

SORTIE:

Line:0

Mettre à jour:
Généralement, la ligne d'erreur du code est 22, je dois donc obtenir ce numéro.

Merci

30
Mustafa Ekici

Essayez plutôt ce hack simple:

Commencez par ajouter cette classe (extension) à votre espace de noms (le plus souvent toplevel class)

public static class ExceptionHelper
{
    public static int LineNumber(this Exception e)
    {

        int linenum = 0;
        try
        {
            //linenum = Convert.ToInt32(e.StackTrace.Substring(e.StackTrace.LastIndexOf(":line") + 5));

            //For Localized Visual Studio ... In other languages stack trace  doesn't end with ":Line 12"
            linenum = Convert.ToInt32(e.StackTrace.Substring(e.StackTrace.LastIndexOf(' ')));

        }


        catch
        {
            //Stack trace is not available!
        }
        return linenum;
    }
}

Et c'est fait! Utilisez la méthode LineNumber quand vous en avez besoin:

try
{
//Do your code here
}
catch (Exception e)
{
int linenum = e.LineNumber();
}
21
pingsft

essaye ça 

Pour obtenir les numéros de ligne dans StackTrace, vous devez disposer des informations de débogage correctes (fichiers PDB) à côté de vos dll/exes. Pour générer les informations de débogage, définissez l'option dans Project Properties -> Build -> Advanced -> Debug Info:

alt text

Le paramétrer sur full devrait suffire (voir le docs MSDN pour connaître le fonctionnement des autres options). Les informations de débogage (c'est-à-dire les fichiers PDB) sont générées pour les configurations de construction Debug par défaut, mais peuvent également être générées pour les configurations de construction Release. 

La génération de PDB pour les versions release vous permet de vous envoyer du code sans les PDB, mais vous pouvez également les déposer à côté des dll si vous avez besoin de numéros de ligne (ou même de joindre un débogueur distant). Une chose à noter est que, dans une version validée, les numéros de ligne peuvent ne pas être entièrement corrects du fait des optimisations apportées par le compilateur ou le compilateur JIT (notamment si les numéros de ligne sont 0).

9
Enigma State

Le problème est que vous essayez d'obtenir le numéro de ligne de la première image de l'exception:

System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());

Cependant, l’exception provient de la ligne non que vous écrivez dans la ligne ExecuteNonQuery, mais quelque part dans cette fonction, éventuellement de plusieurs cadres de pile (c’est-à-dire des appels de fonction imbriqués). Ainsi, la première image (que vous récupérez explicitement à l'aide de GetFrame(0)) se trouve quelque part dans le code de Microsoft (le plus probablement System.Data.dll) pour laquelle vous ne possédez aucun symbole de débogage.

Ecrivez le stacktrace d'exception complet dans votre fonction pour voir ce que je veux dire:

try
{
   // your code ...
}
catch (Exception ex) 
{
   Console.WriteLine(ex);
}

À part l’analyse de stacktrace (c’est-à-dire ex.StackTrace), il n’existe pas de raison fiable pour obtenir le linumber de l’appel "ExecuteNonQuery ()". Je voudrais surtout pas essayer de compter les images d'empilement dans la pile où votre appel à ExecuteNonQuery () se produit.

Je me demande cependant pourquoi vous avez besoin du numéro de lin unique, pourquoi ne pas simplement vous connecter/imprimer/quelle que soit la pile complète. Au moins pour des raisons de diagnostic, cela est beaucoup plus utile de toute façon.

7
Christian.K

Vous pourriez obtenir 0 dans le résultat si vous n'initialisez pas StackTrace pour inclure fileinfo.

enter image description here

Essaye ça

try
{
    //code
}
catch (Exception e)
{
    var lineNumber = new System.Diagnostics.StackTrace(e, true).GetFrame(0).GetFileLineNumber();
}

Cela a fonctionné pour moi.

4
d-coder

Voici un moyen assez facile d'obtenir un tas d'informations à partir de l'objet Exception: Ajoutez simplement un code comme celui-ci à toutes les méthodes potentiellement générant des exceptions:

catch (Exception ex)
{
    String exDetail = String.Format(ExceptionFormatString, ex.Message, Environment.NewLine, ex.Source, ex.StackTrace);
    MessageBox.Show(exDetail);
}

Les informations que vous obtiendrez seront souvent plus spécifiques que vous ne le verriez, notamment en ce qui concerne les numéros de ligne des problèmes sur lesquels vous vous trouvez.

Vous avez peut-être remarqué que String.Format () utilise une constante, à savoir "ExceptionFormatString". C'est une bonne pratique. Ainsi, si vous souhaitez le modifier, après avoir ajouté le code ci-dessus aux méthodes 40 à 11, vous pouvez le modifier à un endroit. Quoi qu'il en soit, la voici:

public static readonly String ExceptionFormatString = "Exception message: {0}{1}Exception Source: {2}{1}Exception StackTrace: {3}{1}";

Bon débogage!

4
B. Clay Shannon

Vous pouvez utiliser la classe System.Diagnostics.StackTrace comme ci-dessous:

public void MethodName()
{
    try
    {
        throw new Exception();
    }
    catch (Exception ex)
    {
        // Get stack trace for the exception with source file information
        var trace = new StackTrace(ex, true);

        // Get the top stack frame
        var frame = trace.GetFrame(0);

        // Get the line number from the stack frame
        var line = frame.GetFileLineNumber();
    }
}
4
VS1

Pour obtenir les numéros de ligne, votre application doit être en mode Debug ou inclure les symboles de débogage dans le même dossier (le fichier .pdb) pour que les numéros de ligne apparaissent. Votre code comme posté devrait alors fonctionner.

1
Rowland Shaw

Dans .NET 4.5, vous pouvez utiliser ExceptionDispatchInfo pour redistribuer vos exceptions au lieu du throw; classique (assurez-vous que les fichiers PDB sont présents ou qu'aucun numéro de ligne ne sera affiché):

    static void A()
    {
        try
        {
            throw new Exception("A");
        }
        catch (Exception e)
        {
            ExceptionDispatchInfo.Capture(e).Throw();
        }
    }

Source: blogpost . Fichiers PDB ne diminuez pas les performances sous Windows.

0
Petre T

la méthode suivante de gestionnaire de journaux de code d'exception fonctionne correctement: 

dans catch :

 catch (Exception ex)
            {
                CommonTools.vAddToLog(ex, EmpID, ErrorCodes.UnDefined);
                Response.Redirect("~/ErrorPage.aspx");
            }

dans AddToLog méthode: 

 string _exMsgErr = string.Empty;
                var frame = oStackTrace.FrameCount > 1 ? oStackTrace.GetFrame(1) : oStackTrace.GetFrame(0);
                if (oException.GetType() == typeof(JOVALException))
                {
                    JOVALException _JOVALEx = (JOVALException)oException;
                    _exMsgErr = _JOVALEx.Message;
                }
                else
                {
                    _exMsgErr = oException.Message;
                }
                ErrorLog oError = new ErrorLog(frame.GetMethod().Name, (string)frame.GetFileName(), (int)frame.GetFileLineNumber(), sCustomErrorMessage == string.Empty ? _exMsgErr : sCustomErrorMessage, sUserID, oErrCode);
                //Cont. your code of log file

Enfin, le fichier journal XML ressemble à ceci: 

<ErrorLog>
<MethodName>FillRolesDDLs</MethodName>
<FileName>
F:\Projects\ERP\ERP\Pages\SystemSettings\Roles.aspx.cs
</FileName>
<LineNumber>61</LineNumber>
<ErrorMesssage>
The given DataRow is not in the current DataRowCollection.
</ErrorMesssage>
<UserID>1</UserID>
<ErrCode>UnDefined</ErrCode>
<Time>15/03/2015 16:23:21.976</Time>
</ErrorLog>
0
Raed Alsaleh