when currying, errors highlight the offending parameter (almost)

This commit is contained in:
Joeri Exelmans 2025-05-13 18:54:31 +02:00
parent 35d1034c67
commit c31ba88dfd
2 changed files with 51 additions and 35 deletions

View file

@ -65,35 +65,36 @@
width: 100%;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam {
background-color: darkred;
color: white;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam:after {
border-left-color: darkred;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam {
/* background-color: rgb(95, 4, 4); */
background-color: pink;
/* color: white; */
color: black;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam:after {
/* border-left-color: rgb(95, 4, 4); */
border-left-color: pink;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam {
/* background-color: rgb(95, 4, 4); */
background-color: pink;
/* color: white; */
color: black;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam:after {
/* border-left-color: rgb(95, 4, 4); */
border-left-color: pink;
}
.functionBlock.unifyError > .functionParams > .outputParam {
background-color: pink;
}
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam {
background-color: pink;
color: black;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam:after {
border-left-color: pink;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam {
background-color: pink;
color: black;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam:after {
border-left-color: pink;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam {
background-color: pink;
color: black;
}
.functionBlock.unifyError > .functionParams > .outputParam > .inputParam > .inputParam > .inputParam:after {
border-left-color: pink;
}
.inputParam.offending {
background-color: darkred !important;
color: white !important;
}
.inputParam.offending:after {
border-left-color: darkred !important;
}

View file

@ -60,7 +60,11 @@ function headlessCallBlock({state, setState}: CallBlockProps) {
setResolved(() => input.resolved); // bubble up the error
}
else if (fn.resolved instanceof Error) {
setResolved(() => fn.resolved); // bubble up the error
// @ts-ignore
setResolved(() => {
// @ts-ignore
return Object.assign(fn.resolved, {depth: (fn.resolved.depth || 0) + 1});
}); // bubble up the error
}
else {
// no errors and at least one is undefined:
@ -79,6 +83,11 @@ function headlessCallBlock({state, setState}: CallBlockProps) {
export function CallBlock({ state, setState }: CallBlockProps) {
const {setFn, setInput, onFnCancel, onInputCancel}
= headlessCallBlock({ state, setState });
// @ts-ignore
console.log('depth:', state.resolved?.depth);
return <span className={"functionBlock" + ((state.resolved instanceof Error) ? " unifyError" : "")}>
<FunctionHeader
fn={state.fn}
@ -91,7 +100,11 @@ export function CallBlock({ state, setState }: CallBlockProps) {
<InputParams
fn={state.fn} setFn={setFn}
input={state.input} setInput={setInput}
onInputCancel={onInputCancel} />
onInputCancel={onInputCancel}
depth={0}
// @ts-ignore
errorDepth={state.resolved instanceof Error ? (state.resolved.depth || 0) : -1}
/>
{/* Output (or Error) */}
{ state.resolved instanceof Error && state.resolved.toString()
|| state.resolved && <><Value dynamic={state.resolved} />&#x2611;</>}
@ -149,14 +162,14 @@ function FunctionHeader({ fn, setFn, input, onFnCancel }) {
}
}
function InputParams({ fn, setFn, input, setInput, onInputCancel }) {
return <div className="inputParam">
function InputParams({ fn, setFn, input, setInput, onInputCancel, depth, errorDepth }) {
return <div className={"inputParam" + (depth === errorDepth ? " offending" : "")}>
{(fn.kind === "call") &&
// if the function we're calling is itself the result of a function call,
// then we render its input parameter nested in our own input parameter box, which is way more readable
// recurse:
<NestedParams fn={fn} setFn={setFn}/>
<NestedParams fn={fn} setFn={setFn} depth={depth} errorDepth={errorDepth}/>
}
{/* Our own input */}
<Editor
@ -168,7 +181,7 @@ function InputParams({ fn, setFn, input, setInput, onInputCancel }) {
</div>;
}
function NestedParams({fn, setFn}) {
function NestedParams({fn, setFn, depth, errorDepth}) {
const {
setFn : setFnFn,
setInput : setFnInput,
@ -179,5 +192,7 @@ function NestedParams({fn, setFn}) {
input={fn.input}
setInput={setFnInput}
onInputCancel={() => {/*todo*/}}
depth={depth+1}
errorDepth={errorDepth}
/>;
}