Skip to main content

TypeNotFoundInAllowTypesException

Thrown when attempting to use a unit key that is not allowed in the model's $unitables configuration.

Namespace

JobMetric\UnitConverter\Exceptions\TypeNotFoundInAllowTypesException

HTTP Status Code

400 Bad Request

Constructor

public function __construct(
string $type,
int $code = 400,
?Throwable $previous = null
)

Parameters

ParameterTypeDescription
$typestringThe unit key/type that was not allowed
$codeintHTTP status code (default: 400)
$previousThrowable|nullPrevious exception for chaining

When Is It Thrown?

This exception is thrown when you try to use a unit key that is not defined in the model's $unitables property.

Understanding $unitables

The $unitables property defines which unit keys are allowed for a model:

class Product extends Model
{
use HasUnit;

// Only these keys are allowed
protected array $unitables = [
'weight' => 'weight',
'length' => 'length',
'width' => 'length',
'height' => 'length',
];
}

Scenario 1: Storing with Invalid Key

$product = Product::find(1);

// 'volume' is not in $unitables
$product->storeUnit('volume', $literId, 5);
// Throws: TypeNotFoundInAllowTypesException

Scenario 2: Getting with Invalid Key

$product = Product::find(1);

// 'temperature' is not in $unitables
$product->getUnit('temperature');
// Throws: TypeNotFoundInAllowTypesException

Scenario 3: Forgetting with Invalid Key

$product = Product::find(1);

// 'pressure' is not in $unitables
$product->forgetUnit('pressure');
// Throws: TypeNotFoundInAllowTypesException

Scenario 4: Unit Type Mismatch

When the unit's type doesn't match the expected type for the key:

class Product extends Model
{
use HasUnit;

protected array $unitables = [
'weight' => 'weight', // expects weight type units
];
}

$product = Product::find(1);

// $meterId is a 'length' type unit, but 'weight' key expects 'weight' type
$product->storeUnit('weight', $meterId, 100);
// Throws: TypeNotFoundInAllowTypesException

Handling the Exception

In Controllers

use JobMetric\UnitConverter\Exceptions\TypeNotFoundInAllowTypesException;

class ProductController extends Controller
{
public function updateUnit(Request $request, Product $product)
{
try {
$product->storeUnit(
$request->key,
$request->unit_id,
$request->value
);

return response()->json(['success' => true]);
} catch (TypeNotFoundInAllowTypesException $e) {
return response()->json([
'error' => 'invalid_unit_key',
'message' => $e->getMessage(),
'allowed_keys' => array_keys($product->getUnitables()),
], 400);
}
}
}

In Form Requests

Validate the key before it reaches the model:

use JobMetric\UnitConverter\Models\Unit;

class StoreProductUnitRequest extends FormRequest
{
public function rules(): array
{
$product = $this->route('product');
$allowedKeys = array_keys($product->getUnitables());

return [
'key' => ['required', 'string', 'in:' . implode(',', $allowedKeys)],
'unit_id' => ['required', 'integer', 'exists:units,id'],
'value' => ['required', 'numeric'],
];
}
}

Global Exception Handler

use JobMetric\UnitConverter\Exceptions\TypeNotFoundInAllowTypesException;

public function register(): void
{
$this->renderable(function (TypeNotFoundInAllowTypesException $e, $request) {
if ($request->expectsJson()) {
return response()->json([
'error' => 'invalid_unit_key',
'message' => $e->getMessage(),
], 400);
}

return redirect()->back()
->withInput()
->withErrors(['key' => $e->getMessage()]);
});
}

Prevention

1. Check Allowed Keys First

$product = Product::find(1);
$unitables = $product->getUnitables();

if (array_key_exists($key, $unitables)) {
$product->storeUnit($key, $unitId, $value);
} else {
// Handle: key not allowed
}

2. Allow All Keys

If you want to allow any key, set $unitables to ['*']:

class FlexibleModel extends Model
{
use HasUnit;

// Allow any unit key
protected array $unitables = ['*'];
}

3. Add Keys at Runtime

Use mergeUnitables() to add keys dynamically:

$product = Product::find(1);

// Add 'volume' key at runtime
$product->mergeUnitables(['volume' => 'volume']);

// Now this works
$product->storeUnit('volume', $literId, 5);

4. Validate Unit Type Match

Ensure the unit type matches the expected type for the key:

use JobMetric\UnitConverter\Models\Unit;

$unit = Unit::find($unitId);
$product = Product::find(1);
$unitables = $product->getUnitables();

if (isset($unitables[$key]) && $unit->type === $unitables[$key]) {
$product->storeUnit($key, $unitId, $value);
} else {
// Handle: type mismatch
}

Configuration Examples

Strict Configuration

Only allow specific keys with specific types:

protected array $unitables = [
'weight' => 'weight',
'length' => 'length',
'width' => 'length',
'height' => 'length',
];

Flexible Configuration

Allow any key (no validation):

protected array $unitables = ['*'];

List Configuration

Keys and expected types are the same:

protected array $unitables = ['weight', 'length', 'volume'];
// Equivalent to: ['weight' => 'weight', 'length' => 'length', 'volume' => 'volume']