You can't create a subset of an enum directly, but splitting this up into multiple types works. You can have FunctionAError with errors that function can produce and a variant for your common errors, and FunctionBError which is similar:
#[derive(Debug, Error)]
enum MyErrorCommon {
#[error("bad value ({0})")]
MyErrorCommon(String),
}
#[derive(Debug, Error)]
enum FunctionAError {
#[error("error a")]
MyErrorA,
Common(#[from] MyErrorCommon),
}
// and same for FunctionBError
The try operator (?) will automatically use From impls to convert errors for you as well. If a function returns a result containing MyErrorCommon in your function and you use ? on it, it gets converted to that function's error type for you. thiserror generates the From impl for you if you use #[from].
Different functions whose possible failure reasons have a non-empty intersection, but don't coincide completely (IDK if this clarifies? I think the example code in the OP is clearer)