object.Exception at std/stdio.d(1321): Enforcement failed - I must be doing something wrong?

monarch_dodra monarchdodra at gmail.com
Thu Aug 15 11:09:20 PDT 2013


On Thursday, 15 August 2013 at 17:41:00 UTC, Colin Grogan wrote:
>     this(LogLevel minLevel = LogLevel.Info, string 
> fileName="logfile.log")
>     {
>         this.minLevel = minLevel;
>         logFile = File(fileName, "w");
>         this.writeMsg(format("Opened file for writing at [%s]", 
> currTimestamp()));
>         logFile.flush();
>         scope(exit){
>             logInfo("End log");
>             logFile.close();
>         }
>     }

This "scope(exit)" runs when you exit the scope, eg: the 
_constructor_, not when your log is destroyed. YOur constructor 
is basically leaving your log file in a closed state, making it 
useless. Instead, use a destroyer:

~this()
{
     logInfo("End log");
     logFile.close();
}

Note though that this will not *actually* work, because since the 
destroyer is run during a collection run, you can't allocate, and 
logInfo calls format, which allocates.

As a matter of fact, you should avoid calling format at all. 
Instead, your "writeMsg" should look like this

void writeMsg(Args...)(string fmt, Args args){
     logFile.writefln(fmt, args);
}

Then, in your log, instead of doing:
             this.writeMsg(format("[%s] %s", timestamp, message));
simply do:
             this.writeMsg("[%s] %s", timestamp, message);

This doesn't fix everything though, and you should also rework 
your "logLevel" functions to not allocate: For example, by making 
"log" accept two strings.


More information about the Digitalmars-d-learn mailing list