How to redirect error but not output and keep text written to console in the right order? (F#)












0















I have two programs that I am running, one of which is run as a child process by the other. When the child process writes to stderr, I want to capture that in the parent process so I can tell if there was an error, and then log the error message to the console just like the child process tried to do.



The problem is that the child process writes several lines of text to stdout immediately after writing to stderr. When the parent process intercepts stderr messages and logs them itself, they get written in parallel with the stdout messages and the text appears in the wrong order.



I have created two F# scripts as a minimal reproduction of this problem. This is the script for the child process:



open System

let logError (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine x
finally Console.ResetColor ()

let logWarning (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Yellow
try stdout.WriteLine x
finally Console.ResetColor ()

let logInfo (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Green
try stdout.WriteLine x
finally Console.ResetColor ()

logError "The quick brown fox jumps over the lazy dog."

logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


And this is the script for the parent process:



open System
open System.Diagnostics

let handleErr (args : DataReceivedEventArgs) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine args.Data
finally Console.ResetColor ()

let p = new Process ()
p.StartInfo.FileName <- "fsi"
p.StartInfo.Arguments <- "child.fsx"
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardError <- true
p.ErrorDataReceived.Add handleErr
p.Start ()
p.BeginErrorReadLine ()
p.WaitForExit ()


The expected output of the child process would be a line in red, followed by a paragraph in yellow, and finally a paragraph in green. When I run the child process on its own that is what gets output. But when I run it through the parent process this happens:
Mangled output



You can see that the error message "The quick brown fox jumped over the lazy dog." printed in the middle of the paragraph that should have printed after it, and the foreground color is incorrect. I have tried to find a solution for this and failed so far, as none of the following things will work:




  • Use locks to allow only one function to print to the console at once - This won't help because the functions are isolated across different processes, not just different threads.

  • Redirect stdout as well as stderr - This makes it impossible to preserve the color of the messages written to stdout.

  • Combine stderr with stdout - I need a way to distinguish between stderr and stdout, so that the parent process can tell if stderr has been written to.


Is there a way in the parent process that I can detect whether the child process has written to stderr, while not redirecting the stderr stream and still letting the child process handle logging to the console?










share|improve this question

























  • Did you try my suggestion? did it work for you?

    – AMieres
    Nov 24 '18 at 21:20











  • @AMieres Thanks for the answer, I don't think it will work though because the parent and child need to be separate processes in my situation. As you said there probably isn't a way to make what I want work apart from using exit codes or IPC, I'll look into those.

    – tjohnson
    Nov 25 '18 at 0:54











  • You have to try it to be sure. I think you will be surprised.

    – AMieres
    Nov 25 '18 at 4:47











  • I am curious if you tried it and if this worked for you: This people seemed to be having the same issue: repl.it/site/blog/stderr

    – AMieres
    Dec 2 '18 at 21:55











  • @AMieres The MailBoxProcessor seems like a really good idea for concurrency. Unfortunately it's not ideal for my situation because I need to be able to run the child processes independently and have them print out to the console, rather than always using a Mailbox agent. I was able to work around the issue for my particular situation, but I'll keep your answer in mind for future work.

    – tjohnson
    Dec 17 '18 at 14:21
















0















I have two programs that I am running, one of which is run as a child process by the other. When the child process writes to stderr, I want to capture that in the parent process so I can tell if there was an error, and then log the error message to the console just like the child process tried to do.



The problem is that the child process writes several lines of text to stdout immediately after writing to stderr. When the parent process intercepts stderr messages and logs them itself, they get written in parallel with the stdout messages and the text appears in the wrong order.



I have created two F# scripts as a minimal reproduction of this problem. This is the script for the child process:



open System

let logError (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine x
finally Console.ResetColor ()

let logWarning (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Yellow
try stdout.WriteLine x
finally Console.ResetColor ()

let logInfo (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Green
try stdout.WriteLine x
finally Console.ResetColor ()

logError "The quick brown fox jumps over the lazy dog."

logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


And this is the script for the parent process:



open System
open System.Diagnostics

let handleErr (args : DataReceivedEventArgs) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine args.Data
finally Console.ResetColor ()

let p = new Process ()
p.StartInfo.FileName <- "fsi"
p.StartInfo.Arguments <- "child.fsx"
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardError <- true
p.ErrorDataReceived.Add handleErr
p.Start ()
p.BeginErrorReadLine ()
p.WaitForExit ()


The expected output of the child process would be a line in red, followed by a paragraph in yellow, and finally a paragraph in green. When I run the child process on its own that is what gets output. But when I run it through the parent process this happens:
Mangled output



You can see that the error message "The quick brown fox jumped over the lazy dog." printed in the middle of the paragraph that should have printed after it, and the foreground color is incorrect. I have tried to find a solution for this and failed so far, as none of the following things will work:




  • Use locks to allow only one function to print to the console at once - This won't help because the functions are isolated across different processes, not just different threads.

  • Redirect stdout as well as stderr - This makes it impossible to preserve the color of the messages written to stdout.

  • Combine stderr with stdout - I need a way to distinguish between stderr and stdout, so that the parent process can tell if stderr has been written to.


Is there a way in the parent process that I can detect whether the child process has written to stderr, while not redirecting the stderr stream and still letting the child process handle logging to the console?










share|improve this question

























  • Did you try my suggestion? did it work for you?

    – AMieres
    Nov 24 '18 at 21:20











  • @AMieres Thanks for the answer, I don't think it will work though because the parent and child need to be separate processes in my situation. As you said there probably isn't a way to make what I want work apart from using exit codes or IPC, I'll look into those.

    – tjohnson
    Nov 25 '18 at 0:54











  • You have to try it to be sure. I think you will be surprised.

    – AMieres
    Nov 25 '18 at 4:47











  • I am curious if you tried it and if this worked for you: This people seemed to be having the same issue: repl.it/site/blog/stderr

    – AMieres
    Dec 2 '18 at 21:55











  • @AMieres The MailBoxProcessor seems like a really good idea for concurrency. Unfortunately it's not ideal for my situation because I need to be able to run the child processes independently and have them print out to the console, rather than always using a Mailbox agent. I was able to work around the issue for my particular situation, but I'll keep your answer in mind for future work.

    – tjohnson
    Dec 17 '18 at 14:21














0












0








0








I have two programs that I am running, one of which is run as a child process by the other. When the child process writes to stderr, I want to capture that in the parent process so I can tell if there was an error, and then log the error message to the console just like the child process tried to do.



The problem is that the child process writes several lines of text to stdout immediately after writing to stderr. When the parent process intercepts stderr messages and logs them itself, they get written in parallel with the stdout messages and the text appears in the wrong order.



I have created two F# scripts as a minimal reproduction of this problem. This is the script for the child process:



open System

let logError (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine x
finally Console.ResetColor ()

let logWarning (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Yellow
try stdout.WriteLine x
finally Console.ResetColor ()

let logInfo (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Green
try stdout.WriteLine x
finally Console.ResetColor ()

logError "The quick brown fox jumps over the lazy dog."

logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


And this is the script for the parent process:



open System
open System.Diagnostics

let handleErr (args : DataReceivedEventArgs) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine args.Data
finally Console.ResetColor ()

let p = new Process ()
p.StartInfo.FileName <- "fsi"
p.StartInfo.Arguments <- "child.fsx"
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardError <- true
p.ErrorDataReceived.Add handleErr
p.Start ()
p.BeginErrorReadLine ()
p.WaitForExit ()


The expected output of the child process would be a line in red, followed by a paragraph in yellow, and finally a paragraph in green. When I run the child process on its own that is what gets output. But when I run it through the parent process this happens:
Mangled output



You can see that the error message "The quick brown fox jumped over the lazy dog." printed in the middle of the paragraph that should have printed after it, and the foreground color is incorrect. I have tried to find a solution for this and failed so far, as none of the following things will work:




  • Use locks to allow only one function to print to the console at once - This won't help because the functions are isolated across different processes, not just different threads.

  • Redirect stdout as well as stderr - This makes it impossible to preserve the color of the messages written to stdout.

  • Combine stderr with stdout - I need a way to distinguish between stderr and stdout, so that the parent process can tell if stderr has been written to.


Is there a way in the parent process that I can detect whether the child process has written to stderr, while not redirecting the stderr stream and still letting the child process handle logging to the console?










share|improve this question
















I have two programs that I am running, one of which is run as a child process by the other. When the child process writes to stderr, I want to capture that in the parent process so I can tell if there was an error, and then log the error message to the console just like the child process tried to do.



The problem is that the child process writes several lines of text to stdout immediately after writing to stderr. When the parent process intercepts stderr messages and logs them itself, they get written in parallel with the stdout messages and the text appears in the wrong order.



I have created two F# scripts as a minimal reproduction of this problem. This is the script for the child process:



open System

let logError (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine x
finally Console.ResetColor ()

let logWarning (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Yellow
try stdout.WriteLine x
finally Console.ResetColor ()

let logInfo (x : string) : unit =
Console.ForegroundColor <- ConsoleColor.Green
try stdout.WriteLine x
finally Console.ResetColor ()

logError "The quick brown fox jumps over the lazy dog."

logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


And this is the script for the parent process:



open System
open System.Diagnostics

let handleErr (args : DataReceivedEventArgs) : unit =
Console.ForegroundColor <- ConsoleColor.Red
try stderr.WriteLine args.Data
finally Console.ResetColor ()

let p = new Process ()
p.StartInfo.FileName <- "fsi"
p.StartInfo.Arguments <- "child.fsx"
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardError <- true
p.ErrorDataReceived.Add handleErr
p.Start ()
p.BeginErrorReadLine ()
p.WaitForExit ()


The expected output of the child process would be a line in red, followed by a paragraph in yellow, and finally a paragraph in green. When I run the child process on its own that is what gets output. But when I run it through the parent process this happens:
Mangled output



You can see that the error message "The quick brown fox jumped over the lazy dog." printed in the middle of the paragraph that should have printed after it, and the foreground color is incorrect. I have tried to find a solution for this and failed so far, as none of the following things will work:




  • Use locks to allow only one function to print to the console at once - This won't help because the functions are isolated across different processes, not just different threads.

  • Redirect stdout as well as stderr - This makes it impossible to preserve the color of the messages written to stdout.

  • Combine stderr with stdout - I need a way to distinguish between stderr and stdout, so that the parent process can tell if stderr has been written to.


Is there a way in the parent process that I can detect whether the child process has written to stderr, while not redirecting the stderr stream and still letting the child process handle logging to the console?







.net f# system.diagnostics processstartinfo redirectstandardoutput






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 4:45







tjohnson

















asked Nov 21 '18 at 22:21









tjohnsontjohnson

691916




691916













  • Did you try my suggestion? did it work for you?

    – AMieres
    Nov 24 '18 at 21:20











  • @AMieres Thanks for the answer, I don't think it will work though because the parent and child need to be separate processes in my situation. As you said there probably isn't a way to make what I want work apart from using exit codes or IPC, I'll look into those.

    – tjohnson
    Nov 25 '18 at 0:54











  • You have to try it to be sure. I think you will be surprised.

    – AMieres
    Nov 25 '18 at 4:47











  • I am curious if you tried it and if this worked for you: This people seemed to be having the same issue: repl.it/site/blog/stderr

    – AMieres
    Dec 2 '18 at 21:55











  • @AMieres The MailBoxProcessor seems like a really good idea for concurrency. Unfortunately it's not ideal for my situation because I need to be able to run the child processes independently and have them print out to the console, rather than always using a Mailbox agent. I was able to work around the issue for my particular situation, but I'll keep your answer in mind for future work.

    – tjohnson
    Dec 17 '18 at 14:21



















  • Did you try my suggestion? did it work for you?

    – AMieres
    Nov 24 '18 at 21:20











  • @AMieres Thanks for the answer, I don't think it will work though because the parent and child need to be separate processes in my situation. As you said there probably isn't a way to make what I want work apart from using exit codes or IPC, I'll look into those.

    – tjohnson
    Nov 25 '18 at 0:54











  • You have to try it to be sure. I think you will be surprised.

    – AMieres
    Nov 25 '18 at 4:47











  • I am curious if you tried it and if this worked for you: This people seemed to be having the same issue: repl.it/site/blog/stderr

    – AMieres
    Dec 2 '18 at 21:55











  • @AMieres The MailBoxProcessor seems like a really good idea for concurrency. Unfortunately it's not ideal for my situation because I need to be able to run the child processes independently and have them print out to the console, rather than always using a Mailbox agent. I was able to work around the issue for my particular situation, but I'll keep your answer in mind for future work.

    – tjohnson
    Dec 17 '18 at 14:21

















Did you try my suggestion? did it work for you?

– AMieres
Nov 24 '18 at 21:20





Did you try my suggestion? did it work for you?

– AMieres
Nov 24 '18 at 21:20













@AMieres Thanks for the answer, I don't think it will work though because the parent and child need to be separate processes in my situation. As you said there probably isn't a way to make what I want work apart from using exit codes or IPC, I'll look into those.

– tjohnson
Nov 25 '18 at 0:54





@AMieres Thanks for the answer, I don't think it will work though because the parent and child need to be separate processes in my situation. As you said there probably isn't a way to make what I want work apart from using exit codes or IPC, I'll look into those.

– tjohnson
Nov 25 '18 at 0:54













You have to try it to be sure. I think you will be surprised.

– AMieres
Nov 25 '18 at 4:47





You have to try it to be sure. I think you will be surprised.

– AMieres
Nov 25 '18 at 4:47













I am curious if you tried it and if this worked for you: This people seemed to be having the same issue: repl.it/site/blog/stderr

– AMieres
Dec 2 '18 at 21:55





I am curious if you tried it and if this worked for you: This people seemed to be having the same issue: repl.it/site/blog/stderr

– AMieres
Dec 2 '18 at 21:55













@AMieres The MailBoxProcessor seems like a really good idea for concurrency. Unfortunately it's not ideal for my situation because I need to be able to run the child processes independently and have them print out to the console, rather than always using a Mailbox agent. I was able to work around the issue for my particular situation, but I'll keep your answer in mind for future work.

– tjohnson
Dec 17 '18 at 14:21





@AMieres The MailBoxProcessor seems like a really good idea for concurrency. Unfortunately it's not ideal for my situation because I need to be able to run the child processes independently and have them print out to the console, rather than always using a Mailbox agent. I was able to work around the issue for my particular situation, but I'll keep your answer in mind for future work.

– tjohnson
Dec 17 '18 at 14:21












1 Answer
1






active

oldest

votes


















2














The typical way for a parent process to know if the child had an error is with the exit code when it is different than zero. Other than that you would need some other type of inter process communication.



I know you said that locks would not work but just in case, I will provide you this possible solution that works with the specific scenario you posted:



This one involves using MailBoxProcessor to sequence the actions. First some helper functions:



module Mailbox =

/// A simple Mailbox processor to serially process Async tasks
/// use:
/// let logThisMsgA = Mailbox.iterA (printfn "%A") (fun msg -> async { printfn "Log: %s" msg } )
/// logThisMsgA.Post "message Async"
///
let iterA hndl f =
MailboxProcessor.Start(fun inbox ->
async {
while true do
try let! msg = inbox.Receive()
do! f msg
with e -> hndl e
}
)

/// A simple Mailbox processor to serially process tasks
/// use:
/// let logThisMsg = Mailbox.iter (printfn "%A") (printfn "Log: %s")
/// logThisMsg.Post "message"
///
let iter hndl f = iterA hndl (fun msg -> async { f msg } )


Here is the Mailbox agent and a function to invoke it:



let sequenceActions = Mailbox.iter (printfn "%A") (fun f -> f() )
let logSeq f txt = sequenceActions.Post <| fun () -> f txt


and your process invokes the functions this way:



logSeq logError   "The quick brown fox jumps over the lazy dog."

logSeq logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

logSeq logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


I hope this helps.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421257%2fhow-to-redirect-error-but-not-output-and-keep-text-written-to-console-in-the-rig%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    The typical way for a parent process to know if the child had an error is with the exit code when it is different than zero. Other than that you would need some other type of inter process communication.



    I know you said that locks would not work but just in case, I will provide you this possible solution that works with the specific scenario you posted:



    This one involves using MailBoxProcessor to sequence the actions. First some helper functions:



    module Mailbox =

    /// A simple Mailbox processor to serially process Async tasks
    /// use:
    /// let logThisMsgA = Mailbox.iterA (printfn "%A") (fun msg -> async { printfn "Log: %s" msg } )
    /// logThisMsgA.Post "message Async"
    ///
    let iterA hndl f =
    MailboxProcessor.Start(fun inbox ->
    async {
    while true do
    try let! msg = inbox.Receive()
    do! f msg
    with e -> hndl e
    }
    )

    /// A simple Mailbox processor to serially process tasks
    /// use:
    /// let logThisMsg = Mailbox.iter (printfn "%A") (printfn "Log: %s")
    /// logThisMsg.Post "message"
    ///
    let iter hndl f = iterA hndl (fun msg -> async { f msg } )


    Here is the Mailbox agent and a function to invoke it:



    let sequenceActions = Mailbox.iter (printfn "%A") (fun f -> f() )
    let logSeq f txt = sequenceActions.Post <| fun () -> f txt


    and your process invokes the functions this way:



    logSeq logError   "The quick brown fox jumps over the lazy dog."

    logSeq logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

    logSeq logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


    I hope this helps.






    share|improve this answer






























      2














      The typical way for a parent process to know if the child had an error is with the exit code when it is different than zero. Other than that you would need some other type of inter process communication.



      I know you said that locks would not work but just in case, I will provide you this possible solution that works with the specific scenario you posted:



      This one involves using MailBoxProcessor to sequence the actions. First some helper functions:



      module Mailbox =

      /// A simple Mailbox processor to serially process Async tasks
      /// use:
      /// let logThisMsgA = Mailbox.iterA (printfn "%A") (fun msg -> async { printfn "Log: %s" msg } )
      /// logThisMsgA.Post "message Async"
      ///
      let iterA hndl f =
      MailboxProcessor.Start(fun inbox ->
      async {
      while true do
      try let! msg = inbox.Receive()
      do! f msg
      with e -> hndl e
      }
      )

      /// A simple Mailbox processor to serially process tasks
      /// use:
      /// let logThisMsg = Mailbox.iter (printfn "%A") (printfn "Log: %s")
      /// logThisMsg.Post "message"
      ///
      let iter hndl f = iterA hndl (fun msg -> async { f msg } )


      Here is the Mailbox agent and a function to invoke it:



      let sequenceActions = Mailbox.iter (printfn "%A") (fun f -> f() )
      let logSeq f txt = sequenceActions.Post <| fun () -> f txt


      and your process invokes the functions this way:



      logSeq logError   "The quick brown fox jumps over the lazy dog."

      logSeq logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

      logSeq logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


      I hope this helps.






      share|improve this answer




























        2












        2








        2







        The typical way for a parent process to know if the child had an error is with the exit code when it is different than zero. Other than that you would need some other type of inter process communication.



        I know you said that locks would not work but just in case, I will provide you this possible solution that works with the specific scenario you posted:



        This one involves using MailBoxProcessor to sequence the actions. First some helper functions:



        module Mailbox =

        /// A simple Mailbox processor to serially process Async tasks
        /// use:
        /// let logThisMsgA = Mailbox.iterA (printfn "%A") (fun msg -> async { printfn "Log: %s" msg } )
        /// logThisMsgA.Post "message Async"
        ///
        let iterA hndl f =
        MailboxProcessor.Start(fun inbox ->
        async {
        while true do
        try let! msg = inbox.Receive()
        do! f msg
        with e -> hndl e
        }
        )

        /// A simple Mailbox processor to serially process tasks
        /// use:
        /// let logThisMsg = Mailbox.iter (printfn "%A") (printfn "Log: %s")
        /// logThisMsg.Post "message"
        ///
        let iter hndl f = iterA hndl (fun msg -> async { f msg } )


        Here is the Mailbox agent and a function to invoke it:



        let sequenceActions = Mailbox.iter (printfn "%A") (fun f -> f() )
        let logSeq f txt = sequenceActions.Post <| fun () -> f txt


        and your process invokes the functions this way:



        logSeq logError   "The quick brown fox jumps over the lazy dog."

        logSeq logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

        logSeq logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


        I hope this helps.






        share|improve this answer















        The typical way for a parent process to know if the child had an error is with the exit code when it is different than zero. Other than that you would need some other type of inter process communication.



        I know you said that locks would not work but just in case, I will provide you this possible solution that works with the specific scenario you posted:



        This one involves using MailBoxProcessor to sequence the actions. First some helper functions:



        module Mailbox =

        /// A simple Mailbox processor to serially process Async tasks
        /// use:
        /// let logThisMsgA = Mailbox.iterA (printfn "%A") (fun msg -> async { printfn "Log: %s" msg } )
        /// logThisMsgA.Post "message Async"
        ///
        let iterA hndl f =
        MailboxProcessor.Start(fun inbox ->
        async {
        while true do
        try let! msg = inbox.Receive()
        do! f msg
        with e -> hndl e
        }
        )

        /// A simple Mailbox processor to serially process tasks
        /// use:
        /// let logThisMsg = Mailbox.iter (printfn "%A") (printfn "Log: %s")
        /// logThisMsg.Post "message"
        ///
        let iter hndl f = iterA hndl (fun msg -> async { f msg } )


        Here is the Mailbox agent and a function to invoke it:



        let sequenceActions = Mailbox.iter (printfn "%A") (fun f -> f() )
        let logSeq f txt = sequenceActions.Post <| fun () -> f txt


        and your process invokes the functions this way:



        logSeq logError   "The quick brown fox jumps over the lazy dog."

        logSeq logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

        logSeq logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."


        I hope this helps.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 22 '18 at 4:40

























        answered Nov 22 '18 at 4:20









        AMieresAMieres

        2,6451511




        2,6451511






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421257%2fhow-to-redirect-error-but-not-output-and-keep-text-written-to-console-in-the-rig%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Costa Masnaga