Detailer
interface has no sense outside of interface/object
errors.Printer
context. I don't see any reason, to make it dedicated from Printer type. The 'fmt' is just module to output formatted texts. Adding additional responsibility to 'fmt' module looks like not good idea. SRP - forever!
I don't see cases for using
error.IsAny(...)
that you suggested. The chained errors will belong different levels of abstraction and they should be checked on their levels. I suppose It'd be useful to implement ability to use errors object with type switch expression.
1: I'm saying it should be used instead of errors.Printer and errors.Formatter.
errors.Formatter is bad because this has more chance for programmer error. If the programmer forgets to print Error(), or return the next error, the purpose of Formatter has an extremely negative impact on anything trying to print it. It leaves for too much human error.
This doesn't violate SRP any more than errors.Formatter does. Either way, fmt, golang.org/x/text/message, etc. will each need to implement errors.Printer, where fmt.Print doesn't have the same function as p.Print. If we didn't want to violate SRP, we should be forced to implement fmt.Formatter rather than a special errors.Formatter.
Using Detailer instead of Formatter also allows for much more parsable errors. For instance, if I wanted JSON for my error, I can now very easily parse my error to:
To do this with Formatter, you would need to create a custom errors.Printer and assume what is error vs what is details, because it is not clear as to what's what.
2: Yeah, honestly the more I think about it, the more I think that it should just be a function that the developer creates for their own needs.
All looks reasonable. I have only couple remarks:
Detailer
interface has no sense outside of interface/objecterrors.Printer
context. I don't see any reason, to make it dedicated from Printer type. The 'fmt' is just module to output formatted texts. Adding additional responsibility to 'fmt' module looks like not good idea. SRP - forever!error.IsAny(...)
that you suggested. The chained errors will belong different levels of abstraction and they should be checked on their levels. I suppose It'd be useful to implement ability to use errors object with type switch expression.1: I'm saying it should be used instead of
errors.Printer
anderrors.Formatter
.errors.Formatter
is bad because this has more chance for programmer error. If the programmer forgets to printError()
, or return the next error, the purpose ofFormatter
has an extremely negative impact on anything trying to print it. It leaves for too much human error.This doesn't violate SRP any more than
errors.Formatter
does. Either way,fmt
,golang.org/x/text/message
, etc. will each need to implementerrors.Printer
, wherefmt.Print
doesn't have the same function asp.Print
. If we didn't want to violate SRP, we should be forced to implementfmt.Formatter
rather than a specialerrors.Formatter
.Using
Detailer
instead ofFormatter
also allows for much more parsable errors. For instance, if I wanted JSON for my error, I can now very easily parse my error to:To do this with
Formatter
, you would need to create a customerrors.Printer
and assume what iserror
vs what isdetails
, because it is not clear as to what's what.2: Yeah, honestly the more I think about it, the more I think that it should just be a function that the developer creates for their own needs.
I seem that name of interface
Formatter
matches better to context offmt
module, than nameDetailer
. The nameDetailer
is better forerrors
module.