「みんな教えて! 選手権!!」開催のお知らせ

C#で、以下のような処理が入ってる書いたプログラムソースがあります
(省略)
try
{
(省略)
}
catch(Exception ex)
{
MessageBox.Show("失敗");
using (StreamWriter js = new StreamWriter($"error.log", true))
{
js.Write(DateTime.Now.ToString("g") + ex.ToString() + "\n");
}
return;
}
(省略)


VisualStudioでリリースビルドしたexeファイルを他の人のPC上で実行させて、この処理が動いた際、error.logに以下が書き込まれてました
2024/06/01 11:50 省略
~ Button_Click(Object sender, RoutedEventArgs e) in
C:\work\001\002\code\Tool\Tool\OutPut.xaml.cs:line 1512

error.log
に出てきたファイルパスは、自分がこのプログラムを作成した時のファイルパスだと思います
どのファイルがどの行でエラー出したかが分かりやすくて良いのですが、作成時のファイルパスが入ってるのがなんか嫌です
これって ex.ToString()
の処理で書き込まれた部分ですが、ファイルパスは出さないようにできますか?

A 回答 (6件)

できません。


コンパイル時のデバッグシンボルなので、一般的にはリリースコンパイル時にデバッグシンボルは含めないことがほとんどです。
よほど本番環境でバカスカエラーを吐くような質の悪いものを提供しているような環境なら別でしょうけど。
その場合、色々な作業をする上でエンドユーザー名でフォルダ分けとかしてると思いますが、あまりパス情報に個人のローカルアカウント名やエンドユーザー名とか入れたくありませんよね。

想定外のエラーを捕捉してエラーログを出力するなら、デバッグシンボルによるスタックトレースに頼るのではなく、それ相応の操作されたリクエストログなどを出力するのがよいかと思います。

どうしてもデバッグシンボルからのスタックトレースで出力したいなら、
自前でちょっと加工するしかありませんね。

テキトーに作りましたが、下記の例だと、例外クラスの拡張メソッドを用意してそれを利用することで、簡素的にパス情報を除去します。
コンパイル時のソシューションパス情報は分からないため全部除去します。
そのため、どのフォルダ構成上にあるファイルなのかは分かりません。

js.Write(DateTime.Now.ToString("g") + ex.ToStringWithoutCompiledPath() + "\n");


public static class ExceptionExtension
{
private static readonly Regex FilePathRegex = new Regex(@"(?<=in )(.+)(?=\\.+\.(cs|vb):)", RegexOptions.Compiled);

public static string ToStringWithoutCompiledPath(this Exception exception)
{
var sb = new StringBuilder($"{exception.GetType().FullName}: {exception.Message}{Environment.NewLine}");

if (exception.StackTrace != null)
{
sb.Append(FilePathRegex.Replace(exception.StackTrace, ""));
}

return sb.ToString();
}
}
    • good
    • 1

No2の方のアドバイスに従い、Exception.ToString() で得られた文字列から


C:\work\001\002\code\Tool\Tool\ を削除するようにしました。

以下のようになります。
catch(Exception ex)
{
MessageBox.Show("失敗");
using (StreamWriter js = new StreamWriter($"error.log", true))
{
//変更開始
string msg = ex.ToString();
msg = msg.Replace(@"C:\work\001\002\code\Tool\Tool\", @"");
js.Write(DateTime.Now.ToString("g") + msg + "\n");
//変更終了
}
return;
}
    • good
    • 1

デバッグ情報(*.pdb)を消せば簡単に消えますが、客先で起きた


不具合の解析が非常に困難になります。
ファイルの構成がバレるより1億倍困ります。
私なら決して消しません。消すやつがいたら殴って叩き出します(^^;
現場の人間が途方にくれないようにしましょう。

#昔ファイル名や識別子にプロレスラーの名前を付けるやつがいましたが
#その類でしょうか? あれは恥ずかしいです(^^;
    • good
    • 1

その情報はデバッグ情報が有効な場合に出ます


他の人に渡す場合はデバッグ情報を除いてコード生成しましょう

https://learn.microsoft.com/ja-jp/dotnet/api/sys …
> 呼び出した Environment.StackTrace 結果が取得

https://learn.microsoft.com/ja-jp/dotnet/api/sys …
> at FullClassName.MethodName(MethodParams) in FileName:LineNumber
> デバッグシンボルが使用できない場合は in で始まる部分文字列全体が省略

https://learn.microsoft.com/ja-jp/dotnet/csharp/ …
> -debug: デバッグ情報を生成します (または生成しません)
    • good
    • 1

Exception.ToString() で得られるものは String なんだから、


StreamWriter.Write() する前に
文字列を好きに加工したらえんちゃうの?
    • good
    • 4
この回答へのお礼

うーん・・・

お礼日時:2024/06/05 01:21

「何処にある何というファイルの何行目でエラーが派生したか」という通知ですのでその一部である「何処にある」だけを消すことは出来ません。



なお、「何処にある」の情報が制作中のソースファイルもので完成後のソースファイルのものではないということでしたら、完成後のソースファイルを置いた場所でコンパイルした実行ファイルを動かしていないということになります。

参考まで。
    • good
    • 0
この回答へのお礼

ありがとう

お礼日時:2024/06/04 12:08

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報

このQ&Aを見た人がよく見るQ&A