2011-12-01 10 views
24

Desidero ottenere il numero di riga del codice che causa l'errore. Per esempio;Come ottenere il numero di riga di errore del codice utilizzando try-catch

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(); 
    } 
} 

così come sappiamo che il codice non funziona, si getterà eccezione Numero di riga di codice che è:

int n = cmd.ExecuteNonQuery(); 

Così come si può ottenere che il numero di riga di utilizzare try-catch? Ho provato ad utilizzare una classe StackTrace ma dà numero di riga come 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()); 
    } 
} 

USCITA:

Line:0 

Aggiornamento:
Solitamente linea di errore di codice è 22 quindi devo ottenere che il numero di .

Grazie

+0

Se siete in modalità 'RELEASE', il numero della linea (tra l'altro) non è più in stacktrace. Il modo più semplice per compilare la modalità 'DEBUG'. Se ancora non funziona, controlla se hai informazioni complete su Debug nelle proprietà del progetto * Avanzate \ Informazioni Debug *. –

+0

@ JiBéDoublevé è in modalità debug, Ed è piena di debug –

+1

Sono i tuoi file PDB nella stessa directory come tutti gli altri file? –

risposta

18

Provate questo semplice trucco, invece:

Prima Aggiungere questo (estensione) classe per lo spazio dei nomi (più essere di classe primo livello):

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; 
    } 
} 

e il suo metodo Usa LineNumber fatto ogni volta che ne avete bisogno!

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

copiare l'intero stack trace in una stringa o StringBuilder utilizzando try/catch in grado di lanciare, vedere l'esempio di seguito

try 
{ 
    //Do some programming 
} 
catch(Exception ex) 
{ 

    //Catch the exception and assign the stack trace 
    StackTrace = ex; 
} 

L'uscita sarà

System.IndexOutOfRangeException: Index was outside the bounds of the array. 
at Program.Run() in C:\Console Application1\Program.cs:line 37  
at Program.Main(String[] args) in C:\Console Application1\Program.cs:line 45 

La prima riga mostra il tipo di eccezione e il messaggio. La seconda riga mostra il numero di file, la funzione e la linea dove l'eccezione è stato gettato

+0

beh questa sembra essere una soluzione, ma sto chiedendo senza analizzare alcuna uscita –

+0

Non abbastanza codice, non riesco a ottenere StackTrace = ex; lavorare. -1 per esempio non funzionante. – Omzig

1

Per ottenere i numeri di riga, è necessario l'applicazione per essere in modalità debug o includono i simboli di debug nella stessa cartella (il file PDB) per visualizzare i numeri di riga. Il codice come pubblicato dovrebbe funzionare.

7

provare questo

per ottenere i numeri di riga nella StackTrace, è necessario avere le informazioni di debug corretto (file PDB) a fianco le DLL/ex. Per generare le informazioni di debug del, impostare l'opzione in Project Properties -> Build -> Advanced -> Debug Info:

alt text

Impostazione a full dovrebbe essere sufficiente (vedere la MSDN docs per quello che le altre opzioni fanno). Le informazioni di debug (ad esempio i file PDB) vengono generate per le configurazioni di build di debug per impostazione predefinita, ma possono anche essere generate per le configurazioni di build di rilascio.

La creazione di PDB per le versioni di rilascio consente di spedire il codice senza PDB, ma di rilasciare i PDB accanto alle DLL se sono necessari numeri di riga (o anche per collegare un debugger remoto). Una cosa da notare è che in una build di rilascio, i numeri di riga potrebbero non essere del tutto corretti a causa delle ottimizzazioni fatte dal compilatore o dal compilatore JIT (questo è particolarmente vero se i numeri di riga mostrano 0).

6

Il problema è che si sta cercando di ottenere il numero di riga del primo fotogramma di eccezione:

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

Tuttavia, l'eccezione non si provengono in prima linea si scrive ExecuteNonQuery, ma da qualche parte all'interno di quella funzione, possibilmente più cornici di stack (cioè chiamate di funzioni annidate) più profonde. Quindi il primo frame (che si recupera esplicitamente usando GetFrame(0)) è da qualche parte all'interno del codice di Microsoft (molto probabilmente System.Data.dll) per il quale non si dispone di simboli di debug.

scrivere lo stacktrace eccezione completa nella funzione per vedere quello che voglio dire:

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

Breve analisi del stacktrace (cioè ex.StackTrace) non v'è alcun motivo per cui affidabile per ottenere il linenumber del "ExecuteNonQuery() "invocazione. Vorrei soprattutto non provare a contare gli stackfram nello stack in cui si verifica la chiamata a ExecuteNonQuery().

Mi chiedo tuttavia, per che cosa è necessario l'unico numero di biancheria, perché non solo registrare/stampare/qualunque sia invece lo stacktrace completo. Almeno per ragioni diagnostiche che è molto più utile comunque.

4

È possibile utilizzare la classe System.Diagnostics.StackTrace come di seguito:

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(); 
    } 
} 
+1

grazie ma è non funziona, la linea = 0 nuovo –

3

È possibile ottenere 0 nel risultato se non si inizializza StackTrace per includere fileinfo.

enter image description here

Prova questa

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

Questo ha funzionato per me.

0

il seguente metodo del gestore del registro eccezioni codice è funziona bene:

in cattura:

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

in AddToLog metodo:

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 

Infine gli sguardi dei file di registro XML in questo modo:

012.
<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> 
2

Ecco un modo piuttosto semplice per ottenere un po 'di informazioni dall'oggetto eccezione: Basta aggiungere il codice come questo per tutti i metodi potenzialmente eccezione lancio:

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

Le informazioni che si ottiene spesso essere più specifico , in particolare per quanto riguarda i numeri di riga di dove si verificano i problemi, di quanto si vedrebbe altrimenti.

avrete notato che lo String.Format() utilizza una costante, vale a dire "ExceptionFormatString". Questa è una buona pratica, quindi se vuoi cambiarla, dopo aver aggiunto il codice sopra a 40-undici metodi, puoi semplicemente cambiarlo in un posto. Ad ogni modo, eccolo:

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

Happy Debugging!

+0

Questo dovrebbe essere l'answ.er accettato – GunWanderer

0

In .NET 4.5 è possibile utilizzare il ExceptionDispatchInfo per rigenerare le vostre eccezioni al posto del classico throw; (assicurarsi che i file PDB ci sono o saranno visualizzati senza numeri di linea):

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

Fonte: blogpost. file PDB don't decrease performance su Windows.

Problemi correlati