Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise all error messages adopting usability pattern #1019

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ lazy val commonSettings = Seq(
Seq("-Ywarn-unused:_,imports", "-Ywarn-unused:imports", "-release", "8")
case Some((2, 11)) =>
Seq()
case _ => sys.error("Unsupported scala version")
case _ => sys.error("The Scala version you are using is not supported. " +
"Please use one of the supported versions: Scala 2.11, 2.12, or 2.13. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. for the "Help them fix it" part, an instruction of which SBT variable should be checked for the current version.
  2. Also there is no "Customer care", only Discord channels. (this also applies to all the other messages)

}
},
javacOptions ++= javacReleaseOption,
Expand Down
4 changes: 3 additions & 1 deletion core/js/src/main/scala/sigma/crypto/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,9 @@ object Platform {
case c: Coll[_] => tpe match {
case STuple(items) => c.tItem == sigma.AnyType && c.length == items.length
case tpeColl: SCollection[_] => true
case _ => sys.error(s"Collection value $c has unexpected type $tpe")
case _ => sys.error(s"The value in the collection $c is not the correct type: $tpe. " +
"Please make sure the value is of the correct type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning of the message has been changed, which makes it less clear (despite many more words).
Please see how the method is used to come up with a clarifying message.

}
case _: Option[_] => tpe.isOption
case _: Tuple2[_, _] => tpe.isTuple && tpe.asTuple.items.length == 2
Expand Down
4 changes: 3 additions & 1 deletion core/js/src/main/scala/sigma/reflection/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ object Platform {
assert(c.clazz == clazz)
c
case _ =>
sys.error(s"Cannot find RClass data for $clazz")
sys.error(s"We couldn't find the data for class $clazz. " +
"Please check that the class name is correct and try again. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
// Uncomment the following line to collect missing reflection data and generate Scala code for it
// memoize(classes)(clazz, new JRClass[T](clazz))
}
Expand Down
4 changes: 3 additions & 1 deletion core/jvm/src/main/scala/sigma/crypto/Platform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ object Platform {
case c: Coll[_] => tpe match {
case STuple(items) => c.tItem == sigma.AnyType && c.length == items.length
case _: SCollection[_] => true
case _ => sys.error(s"Collection value $c has unexpected type $tpe")
case _ => sys.error(s"The value in the collection $c is not the correct type: $tpe. " +
"Please make sure the value is of the correct type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
case _: Option[_] => tpe.isOption
case _: Tuple2[_, _] => tpe.isTuple && tpe.asTuple.items.length == 2
Expand Down
12 changes: 9 additions & 3 deletions core/shared/src/main/scala/sigma/Evaluation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ object Evaluation {
val tpeArg = args(0)
funcRType(stypeToRType(tpeArg), stypeToRType(tpeRange))
case _ =>
sys.error(s"Don't know how to convert SType $t to RType")
sys.error(s"We couldn't process the type $t. " +
"Please ensure that $t is compatible with the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}).asInstanceOf[RType[T#WrappedType]]

/** Transforms RType descriptor of SigmaDsl, which is used during evaluation,
Expand Down Expand Up @@ -82,15 +84,19 @@ object Evaluation {
case ct: CollType[_] => SCollection(rtypeToSType(ct.tItem))
case ft: FuncType[_,_] => SFunc(rtypeToSType(ft.tDom), rtypeToSType(ft.tRange))
case pt: PairType[_,_] => STuple(rtypeToSType(pt.tFst), rtypeToSType(pt.tSnd))
case _ => sys.error(s"Don't know how to convert RType $t to SType")
case _ => sys.error(s"We couldn't process the type $t. " +
"Please ensure that $t is compatible with the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}

/** Convert SigmaDsl representation of tuple to ErgoTree serializable representation. */
def fromDslTuple(value: Any, tupleTpe: STuple): Coll[Any] = value match {
case t: Tuple2[_,_] => TupleColl(t._1, t._2)
case a: Coll[Any]@unchecked if a.tItem == sigma.AnyType => a
case _ =>
sys.error(s"Cannot execute fromDslTuple($value, $tupleTpe)")
sys.error(s"Failed to process the value $value with type $tupleTpe. " +
"Please make sure the value is the correct type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}

/** Convert ErgoTree serializable representation of tuple to SigmaDsl representation. */
Expand Down
57 changes: 43 additions & 14 deletions core/shared/src/main/scala/sigma/ast/SType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,23 @@ object SType {
case _: SOption[_] => x.isInstanceOf[Option[_]]
case t: STuple =>
if (t.items.length == 2) x.isInstanceOf[Tuple2[_,_]]
else sys.error(s"Unsupported tuple type $t")
else sys.error(s"The type $t is not supported. " +
"Please make sure you are using a valid type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
case tF: SFunc =>
if (tF.tDom.length == 1) x.isInstanceOf[Function1[_,_]]
else sys.error(s"Unsupported function type $tF")
else sys.error(s"The type $tF is not supported. " +
"Please make sure you are using a valid type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
case SContext => x.isInstanceOf[Context]
case SAvlTree => x.isInstanceOf[AvlTree]
case SGlobal => x.isInstanceOf[SigmaDslBuilder]
case SHeader => x.isInstanceOf[Header]
case SPreHeader => x.isInstanceOf[PreHeader]
case SUnit => x.isInstanceOf[Unit]
case _ => sys.error(s"Unknown type $tpe")
case _ => sys.error(s"We don't recognize the type $tpe. " +
"Please check the type and make sure it is correct. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}


Expand Down Expand Up @@ -346,7 +352,9 @@ object SNumericType extends STypeCompanion {
override def typeId: TypeCode = 106: Byte

/** Since this object is not used in SMethod instances. */
override def reprClass: RClass[_] = sys.error(s"Shouldn't be called.")
override def reprClass: RClass[_] = sys.error("Please avoid using the reprClass method. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")

}

/** Descriptor of ErgoTree type `Boolean` holding `true` or `false` values. */
Expand All @@ -368,14 +376,19 @@ case object SByte extends SPrimType with SEmbeddable with SNumericType with SMon
override def numericTypeIndex: Int = 0
override def upcast(v: AnyVal): Byte = v match {
case b: Byte => b
case _ => sys.error(s"Cannot upcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")

}
override def downcast(v: AnyVal): Byte = v match {
case b: Byte => b
case s: Short => s.toByteExact
case i: Int => i.toByteExact
case l: Long => l.toByteExact
case _ => sys.error(s"Cannot downcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
}

Expand All @@ -390,13 +403,17 @@ case object SShort extends SPrimType with SEmbeddable with SNumericType with SMo
override def upcast(v: AnyVal): Short = v match {
case x: Byte => x.toShort
case x: Short => x
case _ => sys.error(s"Cannot upcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
override def downcast(v: AnyVal): Short = v match {
case s: Short => s
case i: Int => i.toShortExact
case l: Long => l.toShortExact
case _ => sys.error(s"Cannot downcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
}

Expand All @@ -412,14 +429,18 @@ case object SInt extends SPrimType with SEmbeddable with SNumericType with SMono
case x: Byte => x.toInt
case x: Short => x.toInt
case x: Int => x
case _ => sys.error(s"Cannot upcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
override def downcast(v: AnyVal): Int = v match {
case b: Byte => b.toInt
case s: Short => s.toInt
case i: Int => i
case l: Long => l.toIntExact
case _ => sys.error(s"Cannot downcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
}

Expand All @@ -437,14 +458,18 @@ case object SLong extends SPrimType with SEmbeddable with SNumericType with SMon
case x: Short => x.toLong
case x: Int => x.toLong
case x: Long => x
case _ => sys.error(s"Cannot upcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
override def downcast(v: AnyVal): Long = v match {
case b: Byte => b.toLong
case s: Short => s.toLong
case i: Int => i.toLong
case l: Long => l
case _ => sys.error(s"Cannot downcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
}

Expand All @@ -470,7 +495,9 @@ case object SBigInt extends SPrimType with SEmbeddable with SNumericType with SM
case x: Short => BigInteger.valueOf(x.toLong)
case x: Int => BigInteger.valueOf(x.toLong)
case x: Long => BigInteger.valueOf(x)
case _ => sys.error(s"Cannot upcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
CBigInt(bi)
}
Expand All @@ -480,7 +507,9 @@ case object SBigInt extends SPrimType with SEmbeddable with SNumericType with SM
case x: Short => BigInteger.valueOf(x.toLong)
case x: Int => BigInteger.valueOf(x.toLong)
case x: Long => BigInteger.valueOf(x)
case _ => sys.error(s"Cannot downcast value $v to the type $this")
case _ => sys.error(s"We cannot convert value $v to type $this. " +
"Please check compatibility between the value and the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
CBigInt(bi)
}
Expand Down
4 changes: 3 additions & 1 deletion core/shared/src/main/scala/sigma/data/CSigmaProp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[
// TODO refactor: remove this (it shouldn't be used in interpreter)
override def isValid: Boolean = sigmaTree match {
case p: TrivialProp => p.condition
case _ => sys.error(s"Method CostingSigmaProp.isValid is not defined for $sigmaTree")
case _ => sys.error(s"The method CostingSigmaProp.isValid does not apply to $sigmaTree. " +
"Please make sure to use the correct method for $sigmaTree. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}

override def propBytes: Coll[Byte] = {
Expand Down
14 changes: 10 additions & 4 deletions core/shared/src/main/scala/sigma/kiama/rewriting/Rewriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,9 @@ trait Rewriter {
case _ : NoSuchFieldException =>
val ctors = clazz.getConstructors
if (ctors.length == 0)
sys.error(s"dup no constructors for ${clazz.getName}")
sys.error(s"No constructors found for ${clazz.getName}. " +
"Please ensure the class has accessible constructors. " +
"If the problem persists, reach out to <a href=\"#\">Customer Care</a> for assistance.")
else
(_ : Any, children : Array[AnyRef]) =>
makeInstance(ctors(0), children)
Expand All @@ -260,8 +262,10 @@ trait Rewriter {
ctor.newInstance(unboxPrimitives(ctor, children) : _*)
} catch {
case _ : IllegalArgumentException =>
sys.error(s"""dup illegal arguments: $ctor got (${children.mkString(",")})
|Common cause: term classes are nested in another class, move them to the top level""".stripMargin)
sys.error(s"The function $ctor received the same arguments more than once: ${children.mkString(", ")}. " +
"This usually happens when functions or methods are inside another class. " +
"Try moving them outside the class to fix the problem. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}

/** Unbox primitive values in the given array of children using type information of
Expand Down Expand Up @@ -620,7 +624,9 @@ trait Rewriter {
b += ti
false
case Some(ti) =>
sys.error(s"oneMap: got non-pair $ti")
sys.error(s"We received a non-key-value pair ($ti) in the oneMap function. " +
"Please ensure all inputs to oneMap are in key-value pair format. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
case None =>
b += ct
true
Expand Down
4 changes: 3 additions & 1 deletion core/shared/src/main/scala/sigma/kiama/util/Comparison.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ object Comparison {
case (r1 : AnyRef, r2 : AnyRef) =>
r1 eq r2
case _ =>
sys.error(s"same: comparison of $v1 and $v2, should not be reached")
sys.error(s"An unexpected issue occurred with the values $v1 and $v2. " +
"This should not happen during regular use. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class CoreDataSerializer {
val len = arr.length
assert(arr.length == t.items.length, s"Type $t doesn't correspond to value $arr")
if (len > 0xFFFF)
sys.error(s"Length of tuple ${arr.length} exceeds ${0xFFFF} limit.")
sys.error(s"The tuple length (${arr.length}) is too long (maximum limit is ${0xFFFF}). " +
"Please shorten the tuple to meet the limit. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
var i = 0
while (i < arr.length) {
serialize[SType](arr(i), t.items(i), w)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ class TypeSerializer {
serialize(t2, w)
}
case STuple(items) if items.length < 2 =>
sys.error(s"Invalid Tuple type with less than 2 items $items")
sys.error(s"The Tuple with fewer than 2 items ($items) is invalid. " +
"Please ensure tuples contain at least 2 items for proper functionality. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
case tup: STuple => tup.items.length match {
case 3 =>
// Triple of types
Expand Down
17 changes: 12 additions & 5 deletions data/shared/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ object ErgoBoxCandidate {
val amount = amounts(i)
if (tokensInTx.isDefined) {
val tokenIndex = tokensInTx.get.indexWhere(_ == id, 0) // using equality on Coll
if (tokenIndex == -1) sys.error(s"failed to find token id ($id) in tx's digest index")
if (tokenIndex == -1) sys.error(s"Token ID ($id) not found in the transaction's digest index. " +
"Please check the token ID and try again. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
w.putUInt(tokenIndex)
} else {
w.putBytes(id.toArray)
Expand All @@ -161,7 +163,9 @@ object ErgoBoxCandidate {

val nRegs = box.additionalRegisters.keys.size
if (nRegs + ErgoBox.startingNonMandatoryIndex > 255)
sys.error(s"The number of non-mandatory indexes $nRegs exceeds ${255 - ErgoBox.startingNonMandatoryIndex} limit.")
sys.error(s"The number of non-mandatory indexes ($nRegs) exceeds the maximum limit (${255 - ErgoBox.startingNonMandatoryIndex}). " +
"Please decrease the number of non-mandatory indexes to stay within the limit. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
w.putUByte(nRegs)
// we assume non-mandatory indexes are densely packed from startingNonMandatoryIndex
// this convention allows to save 1 bite for each register
Expand All @@ -173,8 +177,9 @@ object ErgoBoxCandidate {
case Some(v) =>
w.putValue(v)
case None =>
sys.error(s"Set of non-mandatory indexes is not densely packed: " +
s"register R$regId is missing in the range [$startReg .. $endReg]")
sys.error(s"The non-mandatory indexes are not densely packed: register R$regId is missing in the range [$startReg .. $endReg]. " +
"Please fill all registers in this range sequentially. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
}
}
Expand Down Expand Up @@ -207,7 +212,9 @@ object ErgoBoxCandidate {
// in v4.x r.getUInt().toInt is used and may return negative Int in which case
// the error below is thrown
if (digestIndex < 0 || digestIndex >= nDigests)
sys.error(s"failed to find token id with index $digestIndex")
sys.error(s"We couldn't find the token ID linked to the index $digestIndex. " +
"Please make sure the index value is correct. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
val amount = r.getULong() // READ
tokenIds(i) = digestsInTx(digestIndex)
tokenAmounts(i) = amount
Expand Down
16 changes: 12 additions & 4 deletions data/shared/src/main/scala/sigma/ast/SigmaPredef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ object SigmaPredef {
{ case (_, Seq(arg: EvaluatedValue[SString.type]@unchecked)) =>
ErgoAddressEncoder(networkPrefix).fromString(arg.value).get match {
case a: P2PKAddress => SigmaPropConstant(a.pubkey)
case a => sys.error(s"unsupported address $a")
case a => sys.error(s"The address $a is not supported. " +
"Please make sure the address is correct and try again. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
}),
OperationInfo(Constant, "",
Expand All @@ -165,16 +167,22 @@ object SigmaPredef {
PredefFuncInfo(
{ case (Ident(_, SFunc(_, tpe, _)), args) =>
if (args.length != 1)
throw new InvalidArguments(s"Wrong number of arguments in $args: expected one argument")
throw new InvalidArguments(s"The provided inputs ($args) are incorrect. This operation requires only one input. " +
"Please adjust your input to include just one item and try again. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
val str = args.head match {
case StringConstant(s) => s
case _ =>
throw new InvalidArguments(s"invalid argument in $args: expected a string constant")
throw new InvalidArguments(s"The input provided ($args) is invalid. This operation requires a text value. " +
"Please make sure the input is a valid text and try again. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
}
val bytes = Base58.decode(str).get
val res = ValueSerializer.deserialize(bytes)
if (res.tpe != tpe)
throw new InvalidArguments(s"Wrong type after deserialization, expected $tpe, got ${res.tpe}")
throw new InvalidArguments(s"The data type is incorrect. Expected: $tpe, but received: ${res.tpe}. " +
"Please make sure the data matches the expected type. " +
"If the issue keeps happening, contact <a href=\"#\">Customer care</a>.")
res
}),
OperationInfo(Constant, "Deserializes values from Base58 encoded binary data at compile time into a value of type T.",
Expand Down
Loading
Loading