পূর্ণ অভ্যন্তরীণ প্রদর্শনটি করার সঠিক উপায় কী?


155

আমার পূর্ণ দেখানোর উপযুক্ত উপায় কী InnerException

আমি দেখতে পেলাম যে আমার কিছু অভ্যন্তরীণ ধারণাগুলির মধ্যে একটির রয়েছে InnerExceptionএবং এটি বেশ গভীর go

হবে InnerException.ToString()আমার জন্য কাজ অথবা আমি মাধ্যমে লুপ করতে হবে InnerExceptionsএবং আপ একটি বিল্ড Stringসঙ্গে StringBuilder?


কেন আপনার ভিতরের ব্যতিক্রম দেখাতে হবে ??
আকরাম শাহদা

26
@ আকরাম কারণ বেশিরভাগ সময় এটি অভ্যন্তরীণ ব্যতিক্রম আকর্ষণীয়। এর একটি উদাহরণ হ'ল এক্সএমএলসিরালাইজার যা যখনই কিছু ভুল হয়ে যায় কেবল একটি অবৈধপ্রকাশের অনুভূতি ফেলে দেয়। যা ভুল হয়েছে তা অন্তর্নিহিত ব্যতিক্রম।
অ্যাড্রিনিম

4
@ আকরামশাহদা আচ্ছা, আপনি সম্ভবত আপনার লগিংয়ে এই পদ্ধতিটি ব্যবহার করতে চান?
সিডারলফ

উত্তর:


239

আপনি কেবল মুদ্রণ করতে পারেন exception.ToString()- এতে সমস্ত নেস্টেডদের জন্য সম্পূর্ণ পাঠ্যও অন্তর্ভুক্ত থাকবে InnerException



কেবল সংক্ষিপ্ততার জন্য আপনার আসলে .ToString () এর দরকার নেই, কেবলমাত্র ব্যাতিক্রম ব্যবহার করাও এটি করবে।
অ্যালেক্স স্টিফেন্স

3
@ অ্যালেক্সস্টেফেনস আপনি ঠিক বলেছেন তবে কেবল যদি আপনার কোনও কারণের জন্য "স্ট্রিং" এর জন্য অন্তর্নিহিত কাস্টিং থাকে তবে পূর্ববর্তী স্ট্রিংয়ের মতো: "
ব্লে

1
এফওয়াইআই: এটি ToStringঅভ্যন্তরীণ ব্যতিক্রমগুলির জন্য কাস্টম পদ্ধতিগুলিকে কল করবে না কেন এটি বিশদভাবে নয় System সিস্টেম। এক্সপশন T টুস্ট্রিং অভ্যন্তরীণ ব্যতিক্রমগুলির জন্য ভার্চুয়াল টস্ট্রিংকে কল করে?
জেফ বি

45

শুধু ব্যবহার exception.ToString()

http://msdn.microsoft.com/en-us/library/system.exception.tostring.aspx

টোস্ট্রিংয়ের ডিফল্ট বাস্তবায়ন ক্লাসের নামটি গ্রহণ করে যা বর্তমান ব্যতিক্রম ছুঁড়ে ফেলেছে, বার্তাটি, অভ্যন্তরীণ ব্যতিক্রমে টসস্ট্রিংকে কল করার ফলাফল এবং পরিবেশকে স্ট্যাকট্রেস কল করার ফলাফল। এই সদস্যগুলির মধ্যে যদি কোনও নাল হয় তবে এর মানটি ফেরত স্ট্রিংয়ের সাথে অন্তর্ভুক্ত করা হয় না।

যদি কোনও ত্রুটি বার্তা না থাকে বা এটি একটি খালি স্ট্রিং ("") থাকে, তবে কোনও ত্রুটি বার্তা ফিরে আসে না। অভ্যন্তরীণ ব্যতিক্রমের নাম এবং স্ট্যাক ট্রেসের নামটি যদি শূন্য না হয় তবেই ফিরে আসে।

ব্যতিক্রম.ওস্ট্রিং () কল করবে। ব্যতিক্রমটির অভ্যন্তরীণ ব্যতিক্রমের ক্ষেত্রে টুস্ট্রিং () এবং আরও কিছু ...


45

বেশিরভাগ আওয়াজ সরাতে আমি সাধারণত এটি করি:

void LogException(Exception error) {
    Exception realerror = error;
    while (realerror.InnerException != null)
        realerror = realerror.InnerException;

    Console.WriteLine(realerror.ToString())
}    

সম্পাদনা: আমি এই উত্তরটি ভুলে গিয়েছি এবং অবাক হয়েছি যে কেউ আপনাকে দেখায় যে ঠিক করতে পারেন

void LogException(Exception error) {
    Console.WriteLine(error.GetBaseException().ToString())
}    

এই পদ্ধতিটি গভীরতম অভ্যন্তরীণ ব্যতিক্রম বাদে সবকিছু লুকায়। যদি এটি "শূন্য দ্বারা ভাগ করুন" ত্রুটির মতো কিছু ছিল তবে এটি কোথায় ঘটেছে এবং এর ফলে কী ঘটেছিল তা স্পষ্ট হবে না। স্পষ্টতই, একটি সম্পূর্ণ স্ট্যাক ট্রেস সাধারণত অগোছালো ওভারকিল হয় তবে কেবল অভ্যন্তরীণ ব্যতিক্রমগুলি পড়া অন্য চরম। ব্যবহারকারী 3016982 এর উত্তর আরও ভাল। আপনি বাজে ট্রেস ছাড়াই স্ট্যাকের প্রতিটি ব্যতিক্রম বার্তা পান।
জেমসহাক্স

1
@ জেমসহাক্স "ইউজার 3016982" উত্তর কোনটি? তাকে এখানে খুঁজে পাচ্ছি না।
মারাকুজা-রস

User3016982 ThomazMoura হয় দেখুন: stackoverflow.com/users/3016982/thomazmoura
Apfelkuacha

@ জামেসহক্স, অভ্যন্তরীণ ব্যতিক্রমটিতে একটি সম্পূর্ণ স্ট্যাকট্র্যাস রয়েছে যেখানে কোথায় ত্রুটি ঘটেছে এবং এর ফলে কী ঘটেছিল তা দেখায়। মুছে ফেলা স্ট্যাক ট্রেসগুলি থেকে আপনি কী অতিরিক্ত তথ্য পান তা বুঝবেন না। ব্যতিক্রম বার্তাগুলি অন্য জিনিস এবং এটি সমস্ত সংগ্রহ করার জন্য এটি কার্যকর হতে পারে।
অ্যাড্রিনিম

2
আপনি শুধু ব্যবহার করবেন না কেন error.GetBaseException()। আমি বিশ্বাস করি এটি একই রকম হয় ...
রব্বা

37

আপনি সম্পূর্ণ বিশদ বিবরণ (সমস্ত বার্তা এবং স্ট্যাক ট্রেস) এবং প্রস্তাবিত উত্তর চাইলে @ জনের উত্তর হ'ল সেরা সমাধান।

যাইহোক, আপনি কেবল অভ্যন্তরীণ বার্তাগুলি চাইলে এমন কিছু ক্ষেত্রে থাকতে পারে এবং এই ক্ষেত্রে আমি নিম্নলিখিত এক্সটেনশন পদ্ধতিটি ব্যবহার করি:

public static class ExceptionExtensions
{
    public static string GetFullMessage(this Exception ex)
    {
        return ex.InnerException == null 
             ? ex.Message 
             : ex.Message + " --> " + ex.InnerException.GetFullMessage();
    }
}

আমি প্রায়শই এই পদ্ধতিটি ব্যবহার করি যখন আমি যখন ট্রেসিং এবং লগিংয়ের জন্য আলাদা শ্রোতা থাকি এবং তাদের বিষয়ে আলাদা আলাদা মতামত রাখতে চাই। এইভাবে আমার একজন শ্রোতা থাকতে পারে যা .ToString()পদ্ধতিটি ডিবাগ করার জন্য ডেভ টিমকে ইমেলের মাধ্যমে স্ট্যাক ট্রেসের সাথে পুরো ত্রুটি প্রেরণ করে এবং স্ট্যাক ট্রেস ছাড়াই প্রতিদিন ঘটে যাওয়া সমস্ত ত্রুটির ইতিহাসের সাথে ফাইলটিতে লগ-ইন লিখে এমন একটি। .GetFullMessage()পদ্ধতি।


7
এফওয়াইআই যদি exহয় তবে কোনও AggregateExceptionঅভ্যন্তরীণ ব্যতিক্রম এই আউটপুটে অন্তর্ভুক্ত থাকবে না
kornman00

3
এটি স্টক। নেট পদ্ধতি হওয়া উচিত। প্রত্যেকেরই এটি ব্যবহার করা উচিত।
জেমসহাক্স 3'18

9

Messageগভীর ব্যতিক্রমগুলির কেবলমাত্র অংশটি প্রিন্ট করার জন্য , আপনি এরকম কিছু করতে পারেন:

public static string ToFormattedString(this Exception exception)
{
    IEnumerable<string> messages = exception
        .GetAllExceptions()
        .Where(e => !String.IsNullOrWhiteSpace(e.Message))
        .Select(e => e.Message.Trim());
    string flattened = String.Join(Environment.NewLine, messages); // <-- the separator here
    return flattened;
}

public static IEnumerable<Exception> GetAllExceptions(this Exception exception)
{
    yield return exception;

    if (exception is AggregateException aggrEx)
    {
        foreach (Exception innerEx in aggrEx.InnerExceptions.SelectMany(e => e.GetAllExceptions()))
        {
            yield return innerEx;
        }
    }
    else if (exception.InnerException != null)
    {
        foreach (Exception innerEx in exception.InnerException.GetAllExceptions())
        {
            yield return innerEx;
        }
    }
}

লাইন বিরতিতে সীমিত করে তাদের মধ্যে থাকা AggregateExceptionসমস্ত Messageসম্পত্তি মুদ্রণের জন্য এটি অভ্যন্তরীণ সমস্ত ব্যতিক্রমগুলি ( গুলি এর ক্ষেত্রে সহ ) অবিচ্ছিন্নভাবে যায় ।

যেমন

var outerAggrEx = new AggregateException(
    "Outer aggr ex occurred.",
    new AggregateException("Inner aggr ex.", new FormatException("Number isn't in correct format.")),
    new IOException("Unauthorized file access.", new SecurityException("Not administrator.")));
Console.WriteLine(outerAggrEx.ToFormattedString());

বহিরাগত আগ্রাসী প্রাক্তন ঘটেছে।
অভ্যন্তরীণ আগর প্রাক্তন
সংখ্যাটি সঠিক ফর্ম্যাটে নেই।
অননুমোদিত ফাইল অ্যাক্সেস।
প্রশাসক নয়।


আপনার অন্যের কথা শুনতে হবে আরও বিশদের জন্য ব্যতিক্রম বৈশিষ্ট্যগুলি । যেমন Dataকিছু তথ্য থাকবে। আপনি করতে পারেন:

foreach (DictionaryEntry kvp in exception.Data)

সমস্ত উদ্ভূত বৈশিষ্ট্য (বেস Exceptionশ্রেণিতে নয়) পেতে, আপনি এটি করতে পারেন:

exception
    .GetType()
    .GetProperties()
    .Where(p => p.CanRead)
    .Where(p => p.GetMethod.GetBaseDefinition().DeclaringType != typeof(Exception));

+1, এটি আমার মতো প্রায় একই জিনিস। অনুরূপ অন্যান্য ধরণের হ্যান্ডেল IEnumerable<Exception>করার জন্য হার্ড কোডিংয়ের পরিবর্তে কোনও সম্পত্তি বাস্তবায়ন করার বিষয়টি বিবেচনা করবেন না AggregrateException। বাদ দিন p.IsSpecialNameএবং pi.GetIndexParameters().Length != 0সমস্যা এড়াতে। আউটপুটটিতে ব্যতিক্রমের নাম অন্তর্ভুক্ত করাও একটি ভাল ধারণা
অ্যাড্রিয়ানম

সম্পত্তি সম্পর্কিত তথ্য চেক সম্পর্কে অ্যাড্রিয়ানম ভাল পয়েন্ট। ব্যতিক্রম সংগ্রহের জন্য যাচাই করার বিষয়ে, আপনি কোথায় লাইনটি আঁকতে চান তা সবই। নিশ্চিত যে এটিও করা সম্ভব ..
নওফাল

4

আমি করি:

namespace System {
  public static class ExtensionMethods {
    public static string FullMessage(this Exception ex) {
      if (ex is AggregateException aex) return aex.InnerExceptions.Aggregate("[ ", (total, next) => $"{total}[{next.FullMessage()}] ") + "]";
      var msg = ex.Message.Replace(", see inner exception.", "").Trim();
      var innerMsg = ex.InnerException?.FullMessage();
      if (innerMsg is object && innerMsg!=msg) msg = $"{msg} [ {innerMsg} ]";
      return msg;
    }
  }
}

এটি সমস্ত অভ্যন্তরীণ ব্যতিক্রমগুলি "প্রিন্ট করে" এবং সমষ্টিগত এক্সসেপশন এবং কেসগুলিকে পরিচালনা করে যেখানে ইনারএক্সেপশন essমেসেজ বার্তার মতোই


3

আপনি যদি সমস্ত ব্যতিক্রম সম্পর্কিত তথ্য চান তবে ব্যবহার করুন exception.ToString()। এটি সমস্ত অভ্যন্তরীণ ব্যতিক্রম থেকে ডেটা সংগ্রহ করবে।

আপনি যদি কেবলমাত্র মূল ব্যতিক্রম চান তবে ব্যবহার করুন exception.GetBaseException().ToString()। এটি আপনাকে প্রথম ব্যতিক্রম করবে, যেমন অভ্যন্তরীণ ব্যতিক্রম না থাকলে গভীরতম অভ্যন্তরীণ ব্যতিক্রম বা বর্তমান ব্যতিক্রম।

উদাহরণ:

try {
    Exception ex1 = new Exception( "Original" );
    Exception ex2 = new Exception( "Second", ex1 );
    Exception ex3 = new Exception( "Third", ex2 );
    throw ex3;
} catch( Exception ex ) {
    // ex => ex3
    Exception baseEx = ex.GetBaseException(); // => ex1
}

2

নওফালের উত্তরে বিল্ডআপ।

যখন তার উত্তরটি ব্যবহার করার সময় একটি অনুপস্থিত ভেরিয়েবল এগ্রেক্স ছিল, আমি এটি যুক্ত করেছি added

ফাইল এক্সসেপশন এক্সটেনশনস ক্লাস:

// example usage:
// try{ ... } catch(Exception e) { MessageBox.Show(e.ToFormattedString()); }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YourNamespace
{
    public static class ExceptionExtensions
    {

        public static IEnumerable<Exception> GetAllExceptions(this Exception exception)
        {
            yield return exception;

            if (exception is AggregateException )
            {
                var aggrEx = exception as AggregateException;
                foreach (Exception innerEx in aggrEx.InnerExceptions.SelectMany(e => e.GetAllExceptions()))
                {
                    yield return innerEx;
                }
            }
            else if (exception.InnerException != null)
            {
                foreach (Exception innerEx in exception.InnerException.GetAllExceptions())
                {
                    yield return innerEx;
                }
            }
        }


        public static string ToFormattedString(this Exception exception)
        {
            IEnumerable<string> messages = exception
                .GetAllExceptions()
                .Where(e => !String.IsNullOrWhiteSpace(e.Message))
                .Select(exceptionPart => exceptionPart.Message.Trim() + "\r\n" + (exceptionPart.StackTrace!=null? exceptionPart.StackTrace.Trim():"") );
            string flattened = String.Join("\r\n\r\n", messages); // <-- the separator here
            return flattened;
        }
    }
}

আমার একটি ব্যতিক্রম ছিল কারণ:e.StackTrace == null
আন্দ্রেই ক্রাসসটকি

1
আমি আপডেট করেছি e হতে পারে এটি সাহায্য করে
শিমন ডুডকিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.