Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #36693 > unrolled thread

How to handle same sanity checks

Started byCecil Westerhof <Cecil@decebal.nl>
First post2017-06-22 11:10 +0200
Last post2017-06-26 23:34 +0200
Articles 20 on this page of 29 — 10 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  How to handle same sanity checks Cecil Westerhof <Cecil@decebal.nl> - 2017-06-22 11:10 +0200
    Re: How to handle same sanity checks Martin Gregorie <martin@address-in-sig.invalid> - 2017-06-22 10:27 +0000
      Re: How to handle same sanity checks Cecil Westerhof <Cecil@decebal.nl> - 2017-06-22 13:21 +0200
      Re: How to handle same sanity checks Cecil Westerhof <Cecil@decebal.nl> - 2017-06-23 06:51 +0200
      Re: How to handle same sanity checks Robert Klemme <shortcutter@googlemail.com> - 2017-06-24 12:06 +0200
        Re: How to handle same sanity checks Martin Gregorie <martin@address-in-sig.invalid> - 2017-06-24 10:33 +0000
          Re: How to handle same sanity checks Robert Klemme <shortcutter@googlemail.com> - 2017-06-24 16:46 +0200
            Re: How to handle same sanity checks Martin Gregorie <martin@address-in-sig.invalid> - 2017-06-24 19:37 +0000
    Re: How to handle same sanity checks Andreas Leitgeb <avl@logic.at> - 2017-06-22 11:26 +0000
      Re: How to handle same sanity checks Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-22 07:44 -0400
        Re: How to handle same sanity checks Andreas Leitgeb <avl@logic.at> - 2017-06-22 12:30 +0000
    Re: How to handle same sanity checks Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-22 07:40 -0400
      Re: How to handle same sanity checks v_borchert@despammed.com (Volker Borchert) - 2017-06-22 18:33 +0000
        Re: How to handle same sanity checks Cecil Westerhof <Cecil@decebal.nl> - 2017-06-23 06:48 +0200
          Re: How to handle same sanity checks Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-23 09:57 -0400
            Re: How to handle same sanity checks Cecil Westerhof <Cecil@decebal.nl> - 2017-06-23 16:31 +0200
              Re: How to handle same sanity checks Martin Gregorie <martin@address-in-sig.invalid> - 2017-06-23 17:21 +0000
                Re: How to handle same sanity checks Eric Douglas <e.d.programmer@gmail.com> - 2017-06-26 05:21 -0700
                  Re: How to handle same sanity checks Martin Gregorie <martin@address-in-sig.invalid> - 2017-06-26 13:34 +0000
                    Re: How to handle same sanity checks Martin Gregorie <martin@address-in-sig.invalid> - 2017-06-26 15:22 +0000
          Re: How to handle same sanity checks Arne Vajhøj <arne@vajhoej.dk> - 2017-06-25 22:55 -0400
    Re: How to handle same sanity checks Marcel Mueller <news.5.maazl@spamgourmet.org> - 2017-06-22 23:07 +0200
    Re: How to handle same sanity checks Joerg Meier <joergmmeier@arcor.de> - 2017-06-25 09:52 +0200
    Re: How to handle same sanity checks Robert Klemme <shortcutter@googlemail.com> - 2017-06-25 12:31 +0200
      Re: How to handle same sanity checks Arne Vajhøj <arne@vajhoej.dk> - 2017-06-25 14:23 -0400
        Style police (Was: Re: How to handle same sanity checks) Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-25 17:28 -0400
          Re: Style police (Was: Re: How to handle same sanity checks) Arne Vajhøj <arne@vajhoej.dk> - 2017-06-25 19:14 -0400
          Re: Style police (Was: Re: How to handle same sanity checks) Arne Vajhøj <arne@vajhoej.dk> - 2017-06-25 19:19 -0400
            Re: Style police (Was: Re: How to handle same sanity checks) Robert Klemme <shortcutter@googlemail.com> - 2017-06-26 23:34 +0200

Page 1 of 2  [1] 2  Next page →


#36693 — How to handle same sanity checks

FromCecil Westerhof <Cecil@decebal.nl>
Date2017-06-22 11:10 +0200
SubjectHow to handle same sanity checks
Message-ID<87o9tgo0a9.fsf@munus.decebal.nl>
In my code I have several methods that start with:
    if ((n < MIN_VAL) || (n > MAX_VAL)) {
        throw new InvalidParameterException(String.format(ERROR_N, n));
    }

That is not really DRY.

I could write a method like:
    private void checkN(n) {
        if ((n < MIN_VAL) || (n > MAX_VAL)) {
            throw new InvalidParameterException(String.format(ERROR_N, n));
        }
    }

And then replace all the checks with a call to checkN. But then the
exception is generated in the method checkN instead of the method that
has a wrong parameter.
What is the best way to handle this?

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [next] | [standalone]


#36694

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2017-06-22 10:27 +0000
Message-ID<oig626$4rf$1@dont-email.me>
In reply to#36693
On Thu, 22 Jun 2017 11:10:38 +0200, Cecil Westerhof wrote:

> In my code I have several methods that start with:
>     if ((n < MIN_VAL) || (n > MAX_VAL)) {
>         throw new InvalidParameterException(String.format(ERROR_N, n));
>     }
> 
> That is not really DRY.
> 
> I could write a method like:
>     private void checkN(n) {
>         if ((n < MIN_VAL) || (n > MAX_VAL)) {
>             throw new InvalidParameterException(String.format(ERROR_N,
>             n));
>         }
>     }
> 
> And then replace all the checks with a call to checkN. But then the
> exception is generated in the method checkN instead of the method that
> has a wrong parameter.
> What is the best way to handle this?

I agree that using such a method would tidy up the calling code, but if I 
used this type of method I'd generalise it to something like this:

   private void checkInRange(int n, 
                             int lowLimit, 
                             int highLimit,
                             String error)
   {
      String format = "%s: %d is outside range %d - %d";
      if ((n < lowLimit) || (n > highLimit))
         throw new InvalidParameterException(
               String.format(format,error, n, lowLimit, highLimit));
   }


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#36695

FromCecil Westerhof <Cecil@decebal.nl>
Date2017-06-22 13:21 +0200
Message-ID<87k244nu7v.fsf@munus.decebal.nl>
In reply to#36694
On Thursday 22 Jun 2017 12:27 CEST, Martin Gregorie wrote:

> On Thu, 22 Jun 2017 11:10:38 +0200, Cecil Westerhof wrote:
>
>> In my code I have several methods that start with:
>> if ((n < MIN_VAL) || (n > MAX_VAL)) {
>> throw new InvalidParameterException(String.format(ERROR_N, n));
>> }
>>
>> That is not really DRY.
>>
>> I could write a method like:
>> private void checkN(n) {
>> if ((n < MIN_VAL) || (n > MAX_VAL)) {
>> throw new InvalidParameterException(String.format(ERROR_N,
>> n));
>> }
>> }
>>
>> And then replace all the checks with a call to checkN. But then the
>> exception is generated in the method checkN instead of the method
>> that has a wrong parameter. What is the best way to handle this?
>
> I agree that using such a method would tidy up the calling code, but

OK, it is not a big no-no then.


> if I used this type of method I'd generalise it to something like
> this:
>
> private void checkInRange(int n, 
> int lowLimit, 
> int highLimit,
> String error)
> {
> String format = "%s: %d is outside range %d - %d";
> if ((n < lowLimit) || (n > highLimit))
> throw new InvalidParameterException(
> String.format(format,error, n, lowLimit, highLimit));
> }

There is only one range, but it is good to keep in mind for when that
changes.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [prev] | [next] | [standalone]


#36703

FromCecil Westerhof <Cecil@decebal.nl>
Date2017-06-23 06:51 +0200
Message-ID<87bmpfnw7e.fsf@munus.decebal.nl>
In reply to#36694
On Thursday 22 Jun 2017 12:27 CEST, Martin Gregorie wrote:

> I agree that using such a method would tidy up the calling code, but
> if I used this type of method I'd generalise it to something like
> this:
>
> private void checkInRange(int n, 
> int lowLimit, 
> int highLimit,
> String error)
> {
> String format = "%s: %d is outside range %d - %d";
> if ((n < lowLimit) || (n > highLimit))
> throw new InvalidParameterException(
> String.format(format,error, n, lowLimit, highLimit));
> }

I implemented your function. See my reply to Volker Borchert.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [prev] | [next] | [standalone]


#36711

FromRobert Klemme <shortcutter@googlemail.com>
Date2017-06-24 12:06 +0200
Message-ID<er6rt5FbgtsU2@mid.individual.net>
In reply to#36694
On 22.06.2017 12:27, Martin Gregorie wrote:

> I agree that using such a method would tidy up the calling code, but if I
> used this type of method I'd generalise it to something like this:
> 
>     private void checkInRange(int n,
>                               int lowLimit,
>                               int highLimit,
>                               String error)
>     {
>        String format = "%s: %d is outside range %d - %d";
>        if ((n < lowLimit) || (n > highLimit))
>           throw new InvalidParameterException(
>                 String.format(format,error, n, lowLimit, highLimit));
>     }

Premature modularization.  That makes only sense if the variability is 
needed.  Since this is a private method (which should be static btw.) I 
would only do the minimum what is needed.

Cheers

	robert


-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [next] | [standalone]


#36712

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2017-06-24 10:33 +0000
Message-ID<oilf5m$ls2$1@dont-email.me>
In reply to#36711
On Sat, 24 Jun 2017 12:06:28 +0200, Robert Klemme wrote:

> Premature modularization.  That makes only sense if the variability is
> needed.  Since this is a private method (which should be static btw.) I
> would only do the minimum what is needed.
>
Since almost every program I write has a need for both error reporting 
and diagnostic tracing *and* past experience has shown that a well 
thought out diagnostic tracing scheme remains valuable when code is in 
production, you won't be surprised to hear that I have similar facilities 
for use in both C and Java. In the Java case its a single class capable 
of direct output via the error channel but that also has the ability to 
accumulate the last 'n' tracing messages in a circular buffer and to 
output them if an error is being reported (I swiped this idea from a 
mainframe OS, where its ability to show what happened in the last second 
or two before a crash was invaluable).

So I agree that the stand-alone method is a kludge, while at the same 
time its presence does declutter the code and also serves the useful 
purpose of getting rid of repetitive code. However, something like my 
rather more comprehensive diagnostic and reporting facility is more 
generally useful and reusable.
  

-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#36713

FromRobert Klemme <shortcutter@googlemail.com>
Date2017-06-24 16:46 +0200
Message-ID<er7c9iFehreU1@mid.individual.net>
In reply to#36712
On 24.06.2017 12:33, Martin Gregorie wrote:
> On Sat, 24 Jun 2017 12:06:28 +0200, Robert Klemme wrote:
> 
>> Premature modularization.  That makes only sense if the variability is
>> needed.  Since this is a private method (which should be static btw.) I
>> would only do the minimum what is needed.
>>
> Since almost every program I write has a need for both error reporting
> and diagnostic tracing *and* past experience has shown that a well
> thought out diagnostic tracing scheme remains valuable when code is in
> production, you won't be surprised to hear that I have similar facilities
> for use in both C and Java. In the Java case its a single class capable
> of direct output via the error channel but that also has the ability to
> accumulate the last 'n' tracing messages in a circular buffer and to
> output them if an error is being reported (I swiped this idea from a
> mainframe OS, where its ability to show what happened in the last second
> or two before a crash was invaluable).
> 
> So I agree that the stand-alone method is a kludge, while at the same
> time its presence does declutter the code and also serves the useful
> purpose of getting rid of repetitive code. However, something like my
> rather more comprehensive diagnostic and reporting facility is more
> generally useful and reusable.

Maybe my phrasing was ambiguous.  My point is, if it is not used then 
that level of flexibility is superfluous, or rather hurtful.  If all 
ranges and error messages are identical than there is no point in making 
them arguments to a private method which by definition cannot be reused 
outside the class.  If, at some point, more arguments are needed, then 
the usual Java tools will allow to do that change fairly quickly.  Your 
scheme is a whole different story.

Kind regards

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [next] | [standalone]


#36714

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2017-06-24 19:37 +0000
Message-ID<oimf1u$ouk$1@dont-email.me>
In reply to#36713
On Sat, 24 Jun 2017 16:46:09 +0200, Robert Klemme wrote:

> Maybe my phrasing was ambiguous.  My point is, if it is not used then
> that level of flexibility is superfluous, or rather hurtful.  If all
> ranges and error messages are identical than there is no point in making
> them arguments to a private method which by definition cannot be reused
> outside the class.
>
Yes, agreed. If all the ranges are the same and are only used in the one 
class there may be some value in a private method (decluttering the code) 
but, and its a big but, I'd feel inclined to have words with the coder if 
all the error messages were the same on the grounds that, if its just one 
variable that is being range checked and is never modified inside the 
class instance, then it should be checked once and either declared as 
final or stored as an immutable object. OTOH if its a set of variables 
that all must pass the same range check, then the error messages must not 
be the same because they are all different errors and so should deserve 
different descriptions.
 
> Your scheme is a whole different story. 
>
Sure. It hasn't needed to be changed for quite some time now in either 
language incarnation, mainly because its proved flexible enough to do 
everything that is needed without modification. FWIW the circular buffer 
got added when we were looking for a single, relatively rare error in a  
highish volume financial network that, if it didn't have said circular 
buffer, would have churned out MB of diagnostics per day and which would 
have been a horror to analyse. Then I remembered the George 3 circular 
buffer trick - as a result, the next time the problem occurred we got a 
few pages of trace log with the problem message all nicely displayed. 
Sometimes circular buffers really are the best answer! And IIRC turning 
it on scarcely affected the system throughput.


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#36696

FromAndreas Leitgeb <avl@logic.at>
Date2017-06-22 11:26 +0000
Message-ID<slrnoknai9.o2q.avl@logic.at>
In reply to#36693
Cecil Westerhof <Cecil@decebal.nl> wrote:
> In my code I have several methods that start with:
>     if ((n < MIN_VAL) || (n > MAX_VAL)) {
>         throw new InvalidParameterException(String.format(ERROR_N, n));
>     }
> That is not really DRY.
> I could write a method like:
>     private void checkN(n) {
>         if ((n < MIN_VAL) || (n > MAX_VAL)) {
>             throw new InvalidParameterException(String.format(ERROR_N, n));
>         }
>     }
> And then replace all the checks with a call to checkN. But then the
> exception is generated in the method checkN instead of the method that
> has a wrong parameter.

I would not worry about where the exception gets thrown from, as long
as the call-stack includes the "real culprit".

If you really want it thrown at the call-site, there are these slightly
more verbose variants:

Let checkN() *return* the exception (or null if all was ok), then:
   for (Exception e=checkN(...);e!=null;) { throw e; }
Yes, it's weird to use a "for" here, but "if" doesn't allow ad-hoc
declaration of the Exception var. If you declare "e" ahead, then it
becomes: (not much better, imho)
   Exception e; if ((e=checkN(...))!=null) { throw e; }
(You could also combine this with Martin Gregorie's suggestions.)

Another approach is, to wrap creation of the exception and the check
separately:
   private Exception invalPar(...) {
      return new InvalidParameterException(String.format( ... ));
   }
   private boolean checkN(...) { return ((n < MIN_VAL) || (n > MAX_VAL)); }

and at call-site:

   if (checkN(...)) { throw invalPar(...); }

[toc] | [prev] | [next] | [standalone]


#36698

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2017-06-22 07:44 -0400
Message-ID<oigacf$kkm$1@dont-email.me>
In reply to#36696
On 6/22/2017 7:26 AM, Andreas Leitgeb wrote:
> [...]
> If you really want it thrown at the call-site, there are these slightly
> more verbose variants:
> 
> Let checkN() *return* the exception (or null if all was ok), then:
>     for (Exception e=checkN(...);e!=null;) { throw e; }

     Note that this will put checkN() at the top of the stack trace,
not the method that called it.  Javadoc for Throwable (emphasis mine):

	"[...] A throwable contains a snapshot of the execution stack of
	its thread at the time it was *created*. [...]"

-- 
esosman@comcast-dot-net.invalid
Thirteen hundred eight days to go.

[toc] | [prev] | [next] | [standalone]


#36699

FromAndreas Leitgeb <avl@logic.at>
Date2017-06-22 12:30 +0000
Message-ID<slrnokne96.o2q.avl@logic.at>
In reply to#36698
Eric Sosman <esosman@comcast-dot-net.invalid> wrote:
> On 6/22/2017 7:26 AM, Andreas Leitgeb wrote:
>> [...]
>> If you really want it thrown at the call-site, there are these slightly
>> more verbose variants:
>> Let checkN() *return* the exception (or null if all was ok), then:
>>     for (Exception e=checkN(...);e!=null;) { throw e; }
> Note that this will put checkN() at the top of the stack trace,
> not the method that called it.  Javadoc for Throwable (emphasis mine):
> 	"[...] A throwable contains a snapshot of the execution stack of
> 	its thread at the time it was *created*. [...]"

Thanks for the correction!

Seems to have been a long standing wrong belief on my side, and browsing
on Stackoverflow and similar sites, it's an often stated (and also often 
correctly refuted) thing.  C# seems to have it differently, but I can't
use that as an excuse for me, as I haven't done any C# programming.

Sorry to OP for my (in hindsight) useless answer.

[toc] | [prev] | [next] | [standalone]


#36697

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2017-06-22 07:40 -0400
Message-ID<oiga3s$jrd$1@dont-email.me>
In reply to#36693
On 6/22/2017 5:10 AM, Cecil Westerhof wrote:
> In my code I have several methods that start with:
>      if ((n < MIN_VAL) || (n > MAX_VAL)) {
>          throw new InvalidParameterException(String.format(ERROR_N, n));
>      }
> 
> That is not really DRY.
> 
> I could write a method like:
>      private void checkN(n) {
>          if ((n < MIN_VAL) || (n > MAX_VAL)) {
>              throw new InvalidParameterException(String.format(ERROR_N, n));
>          }
>      }
> 
> And then replace all the checks with a call to checkN. But then the
> exception is generated in the method checkN instead of the method that
> has a wrong parameter.
> What is the best way to handle this?

     Tastes surely vary, but for repetitive checks I favor writing
the private internal helper method.  Yes, the caller of doItPlease()
gets an exception originating from internalSanityCheck() instead, but
that shouldn't bother anyone.  doItPlease() will be in the stack
trace anyhow, even though it's not at the very top.

-- 
esosman@comcast-dot-net.invalid
Thirteen hundred eight days to go.

[toc] | [prev] | [next] | [standalone]


#36700

Fromv_borchert@despammed.com (Volker Borchert)
Date2017-06-22 18:33 +0000
Message-ID<oih2hb$bad$1@Gaia.teknon.de>
In reply to#36697
Eric Sosman wrote:
> On 6/22/2017 5:10 AM, Cecil Westerhof wrote:
> > In my code I have several methods that start with:
> >      if ((n < MIN_VAL) || (n > MAX_VAL)) {
> >          throw new InvalidParameterException(String.format(ERROR_N, n));
> >      }
> > 
> > That is not really DRY.
> > 
> > I could write a method like:
> >      private void checkN(n) {
> >          if ((n < MIN_VAL) || (n > MAX_VAL)) {
> >              throw new InvalidParameterException(String.format(ERROR_N, n));
> >          }
> >      }
> > 
> > And then replace all the checks with a call to checkN. But then the
> > exception is generated in the method checkN instead of the method that
> > has a wrong parameter.
> > What is the best way to handle this?
> 
>      Tastes surely vary, but for repetitive checks I favor writing
> the private internal helper method.  Yes, the caller of doItPlease()
> gets an exception originating from internalSanityCheck() instead, but
> that shouldn't bother anyone.  doItPlease() will be in the stack
> trace anyhow, even though it's not at the very top.

That can be a problem with some more-or-less-broken logging frameworks,
and a nuisance if trying to diagnose over the phone.

You can always do something like

	final InvalidParameterException e
	  = new InvalidParameterException(String.format(ERROR_N, n));
	final StackTraceElement[] s = e.getStackTrace();
	e.setStackTrace(Arrays.copyOfRange(s, 1, s.length));
	throw e;

or even

public class Throwables {
	private Throwables() {
	}

	public static <T extends Throwable> T relocate(final T t, final int n) {
		final StackTraceElement[] s = t.getStackTrace();
		if (n < s.length) {
			t.setStackTrace(Arrays.copyOfRange(s, n, s.length));
		}
		return t;
	}
}

and then

	throw Throwables.relocate(new InvalidParameterException(...)), 1);

-- 

"I'm a doctor, not a mechanic." Dr Leonard McCoy <mccoy@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert  <v_borchert@despammed.com>

[toc] | [prev] | [next] | [standalone]


#36702

FromCecil Westerhof <Cecil@decebal.nl>
Date2017-06-23 06:48 +0200
Message-ID<87fuernwav.fsf@munus.decebal.nl>
In reply to#36700
On Thursday 22 Jun 2017 20:33 CEST, Volker Borchert wrote:

> Eric Sosman wrote:
>> On 6/22/2017 5:10 AM, Cecil Westerhof wrote:
>>> In my code I have several methods that start with:
>>> if ((n < MIN_VAL) || (n > MAX_VAL)) {
>>> throw new InvalidParameterException(String.format(ERROR_N, n));
>>> }
>>>
>>> That is not really DRY.
>>>
>>> I could write a method like:
>>> private void checkN(n) {
>>> if ((n < MIN_VAL) || (n > MAX_VAL)) {
>>> throw new InvalidParameterException(String.format(ERROR_N, n));
>>> }
>>> }
>>>
>>> And then replace all the checks with a call to checkN. But then
>>> the exception is generated in the method checkN instead of the
>>> method that has a wrong parameter. What is the best way to handle
>>> this?
>>
>> Tastes surely vary, but for repetitive checks I favor writing the
>> private internal helper method. Yes, the caller of doItPlease()
>> gets an exception originating from internalSanityCheck() instead,
>> but that shouldn't bother anyone. doItPlease() will be in the stack
>> trace anyhow, even though it's not at the very top.
>
> That can be a problem with some more-or-less-broken logging
> frameworks, and a nuisance if trying to diagnose over the phone.
>
> You can always do something like
>
> 	final InvalidParameterException e
> 	  = new InvalidParameterException(String.format(ERROR_N, n));
> 	final StackTraceElement[] s = e.getStackTrace();
> 	e.setStackTrace(Arrays.copyOfRange(s, 1, s.length));
> 	throw e;

That is a very good idea. I have now:
    private static void checkInRange(final int n,
                                     final int lowLimit,
                                     final int highLimit,
                                     final String message) {
        if ((n < lowLimit) || (n > highLimit)) {
            final InvalidParameterException e =
                new InvalidParameterException(
                    String.format(message, lowLimit, highLimit, n));
            final StackTraceElement[] s = e.getStackTrace();
            e.setStackTrace(Arrays.copyOfRange(s, 1, s.length));
            throw e;
        }
    }

Works like a charm.


I use the function also in another check function. This I solved in
the following way:
    private static void checkInRangeStartEnd(final int start,
                                             final int end,
                                             final int lowLimit,
                                             final int highLimit,
                                             final String messageStart,
                                             final String messageEnd) {
        try {
            checkInRange(start, lowLimit, highLimit, messageStart);
            checkInRange(end,   start,    highLimit, messageEnd);
        } catch (final InvalidParameterException e) {
            final StackTraceElement[] s = e.getStackTrace();
            e.setStackTrace(Arrays.copyOfRange(s, 1, s.length));
            throw e;
        }
    }

The code is now more clear and easier to change, while the stack trace
gives the right information.

Thanks.


Probably I should define a function to modify the stack trace.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [prev] | [next] | [standalone]


#36704

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2017-06-23 09:57 -0400
Message-ID<oij6h7$92f$1@dont-email.me>
In reply to#36702
On 6/23/2017 12:48 AM, Cecil Westerhof wrote:
> [... creates a Throwable, then alters the stack trace ...]
> 
> The code is now more clear and easier to change, while the stack trace
> gives the right information.

     It's a matter of opinion, perhaps, but I'd say the stack trace
now gives the *wrong* information.  Specifically, following the
trace to find where the Throwable came from leads to a dead end,
to a place where the Throwable did not arise and could not have
arisen.

     Now, you may hold that this is a "little white lie," but I
still believe it's a lie.  Perhaps it's a little lie, but how
great will your lies grow before you draw the lyin'?

-- 
esosman@comcast-dot-net.invalid
Thirteen hundred seven days to go.

[toc] | [prev] | [next] | [standalone]


#36705

FromCecil Westerhof <Cecil@decebal.nl>
Date2017-06-23 16:31 +0200
Message-ID<871sqaojwk.fsf@munus.decebal.nl>
In reply to#36704
On Friday 23 Jun 2017 15:57 CEST, Eric Sosman wrote:

> On 6/23/2017 12:48 AM, Cecil Westerhof wrote:
>> [... creates a Throwable, then alters the stack trace ...]
>>
>> The code is now more clear and easier to change, while the stack
>> trace gives the right information.
>
> It's a matter of opinion, perhaps, but I'd say the stack trace
> now gives the *wrong* information.  Specifically, following the
> trace to find where the Throwable came from leads to a dead end,
> to a place where the Throwable did not arise and could not have
> arisen.
>
> Now, you may hold that this is a "little white lie," but I
> still believe it's a lie.  Perhaps it's a little lie, but how
> great will your lies grow before you draw the lyin'?

You have a point. I need to think about that. Maybe I could add
something to the message to clear it up. Another possibility would be
to make it parameter driven.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [prev] | [next] | [standalone]


#36706

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2017-06-23 17:21 +0000
Message-ID<oijimh$fg5$1@dont-email.me>
In reply to#36705
On Fri, 23 Jun 2017 16:31:23 +0200, Cecil Westerhof wrote:

> 
> You have a point. I need to think about that. Maybe I could add
> something to the message to clear it up. Another possibility would be to
> make it parameter driven.
>
I generally make a point of designing error messages to be self-
explanatory, so they can be found and fixed without needing to see a 
stackdump. GUI applications display the message to the used as a pop-up 
or in the designated error message area. Non-GUI applications either stop 
with a fatal error or write the error to the error channel and continue 
if its non fatal, e.g if the value is in a file the message will look 
something like "Error: filename:nnnn - error message text" where nnnn is 
the line or record number in the file.


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#36728

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-06-26 05:21 -0700
Message-ID<527ac443-c67d-427f-a024-a09e70f4ede2@googlegroups.com>
In reply to#36706
On Friday, June 23, 2017 at 1:25:12 PM UTC-4, Martin Gregorie wrote:
> I generally make a point of designing error messages to be self-
> explanatory, so they can be found and fixed without needing to see a 
> stackdump. GUI applications display the message to the used as a pop-up 
> or in the designated error message area. Non-GUI applications either stop 
> with a fatal error or write the error to the error channel and continue 
> if its non fatal, e.g if the value is in a file the message will look 
> something like "Error: filename:nnnn - error message text" where nnnn is 
> the line or record number in the file.
> 

Sometimes it's helpful or even necessary to see the entire stack trace for an error.  Sometimes that's harmful clutter if you can get multiple errors around the same time.

Most times it's just necessary to know exactly which line threw the error condition, so when I trap for these I just call a static logging method which reports the class that called it from the stack trace along with the line number, a timestamp, and brief error message.

[toc] | [prev] | [next] | [standalone]


#36730

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2017-06-26 13:34 +0000
Message-ID<oir2hg$ot3$1@dont-email.me>
In reply to#36728
On Mon, 26 Jun 2017 05:21:33 -0700, Eric Douglas wrote:

> Sometimes it's helpful or even necessary to see the entire stack trace
> for an error.  Sometimes that's harmful clutter if you can get multiple
> errors around the same time.
>
Obviously we use different approaches to debugging. 

I find the execution path leading to the error to be considerably more 
useful than a stackdump, which is why I developed my ReportError class. 
Its use makes it possible to leave diagnostic messages in a live program 
and to control the amount of trace detail shown, if any, at run time. The 
impact on performance with tracing off is very small.


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#36732

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2017-06-26 15:22 +0000
Message-ID<oir8s6$igd$1@dont-email.me>
In reply to#36730
On Mon, 26 Jun 2017 13:34:40 +0000, Martin Gregorie wrote:

> On Mon, 26 Jun 2017 05:21:33 -0700, Eric Douglas wrote:
> 
>> Sometimes it's helpful or even necessary to see the entire stack trace
>> for an error.  Sometimes that's harmful clutter if you can get multiple
>> errors around the same time.
>>
> Obviously we use different approaches to debugging.
> 
> I find the execution path leading to the error to be considerably more
> useful than a stackdump, which is why I developed my ReportError class.
> Its use makes it possible to leave diagnostic messages in a live program
> and to control the amount of trace detail shown, if any, at run time.
> The impact on performance with tracing off is very small.

Benchmark: 

The best automatic tracing system I've seen ever was in the 1977 vintage 
Algol68R runtime package Apart from the correctly formatted contents of 
all variables and parameters at this stack level, it gave you the 
execution path through the procedure's code. It showed  "if..then",  
"if..else", "do nn times", etc ... using line numbers to identify the 
conditionals, loop delimiters, etc.

I've seen COBOL runtimes do the almost same job as the Algol 68R one 
nearly as well too. 


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web