Thread overview
Why the hell do exceptions give error in the library rather than the user code?
Sep 14, 2018
Josphe Brigmo
Sep 14, 2018
Jonathan Marler
Sep 14, 2018
Josphe Brigmo
Sep 15, 2018
Vladimir Panteleev
Sep 14, 2018
Neia Neutuladh
Sep 14, 2018
Josphe Brigmo
Sep 14, 2018
Neia Neutuladh
Sep 15, 2018
Vladimir Panteleev
September 14, 2018
std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153):

It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters).


Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack.

September 14, 2018
On Friday, 14 September 2018 at 14:34:36 UTC, Josphe Brigmo wrote:
> std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153):
>
> It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters).
>
>
> Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack.

Not getting a stack trace? What platform are you on and what's the command line you used to compile?

September 14, 2018
On Friday, 14 September 2018 at 14:34:36 UTC, Josphe Brigmo wrote:
> std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153):
>
> It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters).

It's what matters when the exception is caused by a bug in user code. It's what matters when the exception is caused by something environmental and the operation was a narrow, focused operation directed by user code.

If you have a bug caused by something in the depths of a complex library, the full stacktrace matters.

> Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack.

They do, I thought? Let me test quickly:

---
void doThrow()
{
    throw new Exception("here!");
}
void main()
{
    try
        doThrow;
    catch (Exception e)
        writeln(e);
}
---

That prints something like:

object.Exception@scratch.d(7): here!
----------------
scratch.d:7 void scratch.doThrow() [0x9d8acd53]
scratch.d:14 _Dmain [0x9d8acd68]

That's a stacktrace.

And if I don't catch the exception, the runtime still gives me a stacktrace.

You do need to include debug symbols to get filenames and line numbers; just compile with -g.
September 14, 2018
On Friday, 14 September 2018 at 15:40:46 UTC, Jonathan Marler wrote:
> On Friday, 14 September 2018 at 14:34:36 UTC, Josphe Brigmo wrote:
>> std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153):
>>
>> It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters).
>>
>>
>> Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack.
>
> Not getting a stack trace? What platform are you on and what's the command line you used to compile?

I get the main exception. Using windows x86 and visual D with it's default command line and in debug mode.

It seems these are "first chance exceptions" and that they seem to cause multiple problems.


This is the only kind of error I get

std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153): test.txt: Access is denied.
----------------
0x000B043A
0x000B0356
0x000A2899
0x000A2CC0
0x000A2CC0
0x000A2CC0
0x000A2CC0
0x000A11EF
0x000BD0EF
0x000BD06D
0x000BCF01
0x000B2EA8
0x00113B5E
0x00113A51
0x001138FD
0x00113BC8
0x76148744 in BaseThreadInitThunk
0x7795582D in RtlGetAppContainerNamedObjectPath
0x779557FD in RtlGetAppContainerNamedObjectPath




Which is about useless in helping me find the error when I use several file command.
September 14, 2018
On Friday, 14 September 2018 at 15:52:20 UTC, Neia Neutuladh wrote:
> On Friday, 14 September 2018 at 14:34:36 UTC, Josphe Brigmo wrote:
>> std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153):
>>
>> It is very annoying when the only error info I have is pointing to code in a library which tells me absolutely nothing about where the error occurs in the in the user code(which is what matters).
>
> It's what matters when the exception is caused by a bug in user code. It's what matters when the exception is caused by something environmental and the operation was a narrow, focused operation directed by user code.
>
> If you have a bug caused by something in the depths of a complex library, the full stacktrace matters.
>
>> Surely the call stack can be unrolled to find code that exists in the user code? Or at least display several lines like a trace stack.
>
> They do, I thought? Let me test quickly:
>
> ---
> void doThrow()
> {
>     throw new Exception("here!");
> }
> void main()
> {
>     try
>         doThrow;
>     catch (Exception e)
>         writeln(e);
> }
> ---
>
> That prints something like:
>
> object.Exception@scratch.d(7): here!
> ----------------
> scratch.d:7 void scratch.doThrow() [0x9d8acd53]
> scratch.d:14 _Dmain [0x9d8acd68]
>
> That's a stacktrace.
>
> And if I don't catch the exception, the runtime still gives me a stacktrace.
>
> You do need to include debug symbols to get filenames and line numbers; just compile with -g.


It is because you are throwing inside your code. When the throw is from the library, it gives something like this:


std.file.FileException@C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d(3153): test.txt: Access is denied.
----------------
0x000B043A
0x000B0356
0x000A2899
0x000A2CC0
0x000A2CC0
0x000A2CC0
0x000A2CC0
0x000A11EF
0x000BD0EF
0x000BD06D
0x000BCF01
0x000B2EA8
0x00113B5E
0x00113A51
0x001138FD
0x00113BC8
0x76148744 in BaseThreadInitThunk
0x7795582D in RtlGetAppContainerNamedObjectPath
0x779557FD in RtlGetAppContainerNamedObjectPath


Where the error is from file. In visual D this always breaks in to the library(which is very annoying but it does show a full stack trace and lets one view the frame).
I could wrap my entire program in a try catch and maybe that will offer some new information, but It seems pointless to do that. The stack should be displayed and much of the nonsense removed(like the 20 lines of pointers which is useless to me(they will be invalid when the program exists so why show them?).
September 14, 2018
On Friday, 14 September 2018 at 16:43:04 UTC, Josphe Brigmo wrote:
> It is because you are throwing inside your code. When the throw is from the library, it gives something like this:

std.exception.ErrnoException@std/stdio.d(430): Cannot open file `/doesntexist' in mode `w' (Permission denied)
----------------
/usr/include/dmd/phobos/std/exception.d:515 @safe void std.exception.bailOut!(std.exception.ErrnoException).bailOut(immutable(char)[], ulong, scope const(char)[]) [0x37130b11]
??:? @safe shared(core.stdc.stdio._IO_FILE)* std.exception.enforce!(std.exception.ErrnoException).enforce!(shared(core.stdc.stdio._IO_FILE)*).enforce(shared(core.stdc.stdio._IO_FILE)*, lazy const(char)[], immutable(char)[], ulong) [0x3713ed76]
??:? ref @safe std.stdio.File std.stdio.File.__ctor(immutable(char)[], scope const(char)[]) [0x371345cc]
scratch.d:7 void scratch.doThrow() [0x371307db]
scratch.d:14 _Dmain [0x37130838]

You're on Windows, by the look of it. Windows ships debug symbols in separate files. Do you have the debug symbols (*.pdb files) somewhere accessible? Did you at least compile your own code with -g to generate debug symbols for it?
September 15, 2018
On Friday, 14 September 2018 at 16:40:01 UTC, Josphe Brigmo wrote:
> This is the only kind of error I get

Compile with -g.

September 15, 2018
On Friday, 14 September 2018 at 14:34:36 UTC, Josphe Brigmo wrote:
> Why the hell do exceptions give error in the library rather than the user code?

D exceptions can provide context in two ways:

- Stack trace, for which you need to compile with debug symbols enabled (-g).

- A file name and line number, which can be passed as parameters, and usually have the default value of the `new FileException` expression's location.

What you're seeing is the second. As you've observed, it is mainly designed to provide context when exceptions are thrown in user code, especially when debug information is not available.

Although it's possible to capture the file/line in library functions and pass them down to exception objects, it is impractical to do it for every library function. The stack trace needs to be used in such cases. Still, some functions dealing with error handling do this, e.g. std.exception.enforce.

In the future, please post questions about learning or using D in the "learn" group:

https://forum.dlang.org/group/learn