Error Handling and Debugging Techniques

1. @debug Directive for Development Logging

Directive Syntax Output Use Case
@debug @debug $value; Prints to stderr Development logging
Multiple Values @debug $var1, $var2; Comma-separated output Compare values
Expressions @debug 10px + 5px; Evaluated result Test calculations
Type Inspection @debug type-of($var); Data type Type checking
Map Inspection @debug map-keys($map); Map structure Debug data structures

Example: Basic debugging with @debug

// Simple value debugging
$primary-color: #1976d2;
@debug $primary-color;
// Output: styles.scss:2 DEBUG: #1976d2

// Multiple values
$width: 300px;
$height: 200px;
@debug "Width:", $width, "Height:", $height;
// Output: styles.scss:5 DEBUG: "Width:", 300px, "Height:", 200px

// Expression debugging
@debug 100px / 16px; 
// Output: styles.scss:7 DEBUG: 6.25

// Type checking
$value: "hello";
@debug type-of($value);
// Output: styles.scss:9 DEBUG: string

// Map debugging
$theme: (
  primary: #1976d2,
  secondary: #dc004e
);
@debug map-keys($theme);
// Output: styles.scss:13 DEBUG: primary, secondary

@debug map-get($theme, primary);
// Output: styles.scss:15 DEBUG: #1976d2

Example: Advanced debugging techniques

@use 'sass:meta';
@use 'sass:map';

// Debug function for formatted output
@mixin debug-info($label, $value) {
  @debug "=== #{$label} ===";
  @debug "  Type: #{meta.type-of($value)}";
  @debug "  Value: #{$value}";
  
  @if meta.type-of($value) == 'map' {
    @debug "  Keys: #{map.keys($value)}";
    @debug "  Values: #{map.values($value)}";
  } @else if meta.type-of($value) == 'list' {
    @debug "  Length: #{length($value)}";
    @debug "  Items: #{$value}";
  }
}

// Usage
$colors: (
  primary: #1976d2,
  secondary: #dc004e,
  success: #4caf50
);

@include debug-info('Theme Colors', $colors);
// Output:
// === Theme Colors ===
//   Type: map
//   Value: (primary: #1976d2, secondary: #dc004e, success: #4caf50)
//   Keys: primary, secondary, success
//   Values: #1976d2, #dc004e, #4caf50

// Conditional debugging
$debug-mode: true;

@mixin debug($message) {
  @if $debug-mode {
    @debug $message;
  }
}

// Function debugging
@function calculate-rem($px) {
  @debug "Converting: #{$px}px to rem";
  $rem: $px / 16;
  @debug "Result: #{$rem}rem";
  @return $rem * 1rem;
}

$font-size: calculate-rem(18);
// Output:
// Converting: 18px to rem
// Result: 1.125rem

Example: Debug breakpoint in compilation

// Debug during loop iterations
$breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
);

@each $name, $size in $breakpoints {
  @debug "Processing breakpoint: #{$name} = #{$size}";
  
  @media (min-width: $size) {
    .container-#{$name} {
      @debug "  Creating .container-#{$name}";
      max-width: $size;
    }
  }
}

// Debug color transformations
@function debug-color-transform($color, $operation, $amount) {
  @debug "Original color: #{$color}";
  
  $result: null;
  @if $operation == 'lighten' {
    $result: lighten($color, $amount);
  } @else if $operation == 'darken' {
    $result: darken($color, $amount);
  }
  
  @debug "After #{$operation}(#{$amount}): #{$result}";
  @return $result;
}

$base: #1976d2;
$lighter: debug-color-transform($base, 'lighten', 20%);
// Output:
// Original color: #1976d2
// After lighten(20%): #64b5f6

2. @warn Directive for Deprecation Warnings

Directive Behavior Use Case Impact
@warn Prints warning, continues compilation Deprecation notices Non-fatal alerts
Stack Trace Shows file and line number Track warning source Easy debugging
Conditional Warnings Warn based on conditions Value validation Better error messages
--quiet Suppress warnings with flag Production builds Clean output

Example: Deprecation warnings

// Deprecation warning for old API
@mixin old-button($color) {
  @warn "The old-button mixin is deprecated. Use new-button instead.";
  background: $color;
  padding: 10px 20px;
}

// Better deprecation with migration path
@mixin legacy-grid($cols: 12) {
  @warn "legacy-grid is deprecated since v2.0. " +
        "Use CSS Grid with grid-template-columns instead. " +
        "See: https://docs.example.com/migration";
  
  width: 100% / $cols;
  float: left;
}

// Warn about parameter changes
@mixin button($bg-color, $text-color: null) {
  @if $text-color == null {
    @warn "The text-color parameter will become required in v3.0. " +
          "Please provide an explicit text color.";
    $text-color: white; // Fallback
  }
  
  background: $bg-color;
  color: $text-color;
}

// Usage triggers warning:
.my-button {
  @include button(#1976d2);
  // Warning: The text-color parameter will become required in v3.0...
}

Example: Value validation warnings

@use 'sass:math';
@use 'sass:meta';

// Warn about invalid values
@function safe-divide($a, $b) {
  @if $b == 0 {
    @warn "Division by zero! Returning 0 instead.";
    @return 0;
  }
  @return math.div($a, $b);
}

// Warn about type mismatches
@mixin font-size($size) {
  @if meta.type-of($size) != 'number' {
    @warn "font-size expects a number, got #{meta.type-of($size)}: #{$size}";
    @return;
  }
  
  @if not math.is-unitless($size) and math.unit($size) != 'px' and math.unit($size) != 'rem' {
    @warn "font-size expects px or rem units, got: #{math.unit($size)}";
  }
  
  font-size: $size;
}

// Warn about out-of-range values
@mixin opacity($value) {
  @if $value < 0 or $value > 1 {
    @warn "Opacity should be between 0 and 1, got: #{$value}. Clamping value.";
    $value: math.clamp(0, $value, 1);
  }
  
  opacity: $value;
}

// Warn about browser compatibility
@mixin backdrop-filter($value) {
  @warn "backdrop-filter has limited browser support. " +
        "Consider providing a fallback background color.";
  
  backdrop-filter: $value;
  -webkit-backdrop-filter: $value;
}

// Warn about performance concerns
@mixin deep-nesting-check($level) {
  @if $level > 3 {
    @warn "Nesting level #{$level} detected. " +
          "Deep nesting (>3 levels) can hurt performance and specificity.";
  }
}

Example: Configuration and environment warnings

// Warn about missing configuration
$config: () !default;

@function get-config($key) {
  @if not map-has-key($config, $key) {
    @warn "Configuration key '#{$key}' not found. Using default value.";
    @return null;
  }
  
  @return map-get($config, $key);
}

// Warn about conflicting settings
$use-flexbox: true !default;
$use-float: true !default;

@if $use-flexbox and $use-float {
  @warn "Both flexbox and float layout systems are enabled. " +
        "This may cause conflicts. Disable one in your configuration.";
}

// Environment-specific warnings
$environment: 'development' !default;

@if $environment == 'production' {
  @if $debug-mode == true {
    @warn "Debug mode is enabled in production environment! " +
          "Set $debug-mode: false for production.";
  }
}

// Warn about large file sizes
@mixin check-utility-classes($count) {
  @if $count > 100 {
    @warn "Generating #{$count} utility classes. " +
          "Consider using a utility framework or PurgeCSS to reduce CSS size.";
  }
}

3. @error Directive for Custom Error Messages

Directive Behavior Use Case Impact
@error Stops compilation immediately Critical validation failures Prevents broken output
Required Parameters Validate required arguments Function/mixin safety Better API contracts
Type Validation Ensure correct data types Type safety Catch bugs early
Range Validation Check value boundaries Prevent invalid CSS Guaranteed valid output

Example: Parameter validation with @error

@use 'sass:meta';
@use 'sass:list';

// Validate required parameters
@function calculate-spacing($multiplier) {
  @if $multiplier == null {
    @error "calculate-spacing() requires a $multiplier parameter.";
  }
  
  @return $multiplier * 8px;
}

// Type validation
@mixin text-color($color) {
  @if meta.type-of($color) != 'color' {
    @error "text-color() expects a color, got #{meta.type-of($color)}: #{$color}";
  }
  
  color: $color;
}

// Multiple allowed types
@function parse-size($value) {
  $type: meta.type-of($value);
  
  @if $type != 'number' and $type != 'string' {
    @error "parse-size() expects number or string, got #{$type}: #{$value}";
  }
  
  @return $value;
}

// Enum-like validation
@mixin text-align($align) {
  $valid-values: ('left', 'center', 'right', 'justify');
  
  @if not list.index($valid-values, $align) {
    @error "text-align() expects one of #{$valid-values}, got: #{$align}";
  }
  
  text-align: $align;
}

// Usage that triggers error:
.element {
  @include text-align('middle'); // ❌ Error!
  // Error: text-align() expects one of ("left", "center", "right", "justify"), got: "middle"
}

Example: Range and value validation

@use 'sass:math';

// Range validation
@function clamp-opacity($value) {
  @if meta.type-of($value) != 'number' {
    @error "Opacity must be a number, got: #{$value}";
  }
  
  @if $value < 0 or $value > 1 {
    @error "Opacity must be between 0 and 1, got: #{$value}";
  }
  
  @return $value;
}

// Unit validation
@function validate-spacing($value) {
  @if not math.is-unitless($value) {
    $unit: math.unit($value);
    $valid-units: ('px', 'rem', 'em', '%');
    
    @if not index($valid-units, $unit) {
      @error "Spacing must use px, rem, em, or %, got: #{$unit}";
    }
  }
  
  @return $value;
}

// Positive number validation
@function positive-number($value, $name: 'value') {
  @if meta.type-of($value) != 'number' {
    @error "#{$name} must be a number, got: #{meta.type-of($value)}";
  }
  
  @if $value <= 0 {
    @error "#{$name} must be positive, got: #{$value}";
  }
  
  @return $value;
}

// Grid columns validation
@mixin grid-columns($count) {
  @if $count < 1 or $count > 12 {
    @error "Grid columns must be between 1 and 12, got: #{$count}";
  }
  
  @if $count != math.round($count) {
    @error "Grid columns must be an integer, got: #{$count}";
  }
  
  grid-template-columns: repeat($count, 1fr);
}

Example: Configuration and dependency validation

@use 'sass:map';

// Validate required configuration
$theme-config: () !default;

@function require-config($key) {
  @if not map.has-key($theme-config, $key) {
    @error "Missing required configuration: '#{$key}'. " +
           "Please define $theme-config: (#{$key}: ...) before importing.";
  }
  
  @return map.get($theme-config, $key);
}

// Validate map structure
@function validate-theme($theme) {
  $required-keys: ('primary', 'secondary', 'background', 'text');
  
  @each $key in $required-keys {
    @if not map.has-key($theme, $key) {
      @error "Theme missing required key: '#{$key}'. " +
             "Required keys: #{$required-keys}";
    }
  }
  
  @return $theme;
}

// Validate version compatibility
$sass-version: '1.69.0' !default;

@function check-version($min-version) {
  // Simple version check (in real code, parse properly)
  @if $sass-version < $min-version {
    @error "This library requires Sass #{$min-version} or higher. " +
           "You are using Sass #{$sass-version}. Please upgrade.";
  }
  
  @return true;
}

// Validate mutual exclusivity
@mixin validate-layout-mode($mode) {
  $valid-modes: ('flex', 'grid', 'float');
  
  @if not index($valid-modes, $mode) {
    @error "Invalid layout mode: '#{$mode}'. " +
           "Must be one of: #{$valid-modes}";
  }
}

// Check for circular dependencies
$_importing: () !global;

@mixin check-circular-import($module-name) {
  @if index($_importing, $module-name) {
    @error "Circular import detected: #{$module-name} is already being imported. " +
           "Import stack: #{$_importing}";
  }
  
  $_importing: append($_importing, $module-name) !global;
}

4. Stack Trace Reading and Error Resolution

Stack Trace Part Information How to Read Action
Error Message What went wrong First line of output Understand the problem
File Path Where error occurred filename.scss:line:column Navigate to file
Backtrace Call chain Indented list of calls Trace execution path
Source Excerpt Code context Lines around error See actual code
Caret (^) Exact error position Points to character Pinpoint issue

Example: Reading a typical Sass error

// Error output example:
Error: Undefined variable.

3 │   color: $primry-color; // Typo!
  │          ^^^^^^^^^^^^^

  styles.scss 3:10  root stylesheet

// Breaking it down:
// 1. "Undefined variable" - The problem
// 2. Line 3, Column 10 - Exact location
// 3. The caret points to the typo: $primry-color
// 4. Should be: $primary-color

// Resolution:
.button {
  color: $primary-color; // Fixed!
}

Example: Understanding nested stack traces

// Complex error with multiple levels
Error: $color: transparant is not a color.

8background: mix(white, $color, 20%);
  │               ^^^^^^^^^^^^^^^^^^^^^^^

  _functions.scss 8:15  lighten-color()
  _theme.scss 15:12     create-theme()
  main.scss 23:3        root stylesheet

// Reading the stack trace (bottom to top):
// 1. main.scss:23 - Called create-theme()
// 2. _theme.scss:15 - create-theme() called lighten-color()
// 3. _functions.scss:8 - lighten-color() tried to mix colors
// 4. Error: 'transparant' is not a color (typo: should be 'transparent')

// Trace the error path:
// main.scss
@use 'theme';
$my-theme: create-theme('transparant'); // ❌ Typo here!

// _theme.scss
@use 'functions';
@function create-theme($bg) {
  @return lighten-color($bg); // Passes typo to next function
}

// _functions.scss
@function lighten-color($color) {
  @return mix(white, $color, 20%); // ❌ Fails here because $color is invalid
}

// Resolution:
$my-theme: create-theme('transparent'); // ✅ Fixed!

Example: Common error patterns and solutions

// 1. Undefined Variable
// Error: Undefined variable.
$primary: #1976d2;
.button { color: $priamry; } // Typo
// Solution: Fix spelling or import the file with the variable

// 2. Invalid CSS
// Error: Expected expression.
.box {
  width: ; // Missing value
}
// Solution: Provide a value

// 3. Type Error
// Error: $weight: "bold" is not a number.
font-weight: mix(400, "bold", 50%); // Can't mix number and string
// Solution: Use correct types

// 4. Division
// Error: Undefined operation "300px / 16".
font-size: 300px / 16; // Sass doesn't auto-divide
// Solution: Use math.div()
@use 'sass:math';
font-size: math.div(300px, 16);

// 5. Missing Import
// Error: Undefined mixin.
.button { @include flex-center; } // Mixin not imported
// Solution: @use the file containing the mixin

// 6. Circular Import
// Error: Module loop: circular import
// _a.scss imports _b.scss, _b.scss imports _a.scss
// Solution: Refactor to break the cycle

// 7. Invalid Selector
// Error: Invalid CSS after "...": expected selector
.#{$var} {
  .& { } // Can't use & at start
}
// Solution: &.class or .class&

// 8. Map Error
// Error: (primary: #1976d2, secondary: #dc004e) is not a color.
$colors: (primary: #1976d2);
background: $colors; // Trying to use map as color
// Solution: background: map.get($colors, primary);

// 9. Incompatible Units
// Error: Incompatible units px and %.
width: 100px + 50%; // Can't add different units
// Solution: Use calc() or convert units

// 10. @extend Outside
// Error: @extend may only be used within style rules.
@extend %placeholder; // At root level
// Solution: Move inside a selector

5. Debugging Tools and Browser Integration

Tool Feature Platform Use Case
Chrome DevTools Source maps, CSS inspector Chrome, Edge Live debugging
Firefox DevTools Style editor, source maps Firefox CSS debugging
Safari Web Inspector Styles pane, sources Safari macOS/iOS debugging
VS Code Debugger Breakpoints in SCSS VS Code Pre-compilation debug
Sass Playground Online compiler Web Quick testing
Source Maps Map CSS to SCSS All browsers Find original source

Example: Chrome DevTools debugging workflow

// 1. Enable source maps in compilation
sass --watch --source-map src/scss:dist/css

// 2. Source SCSS file: src/scss/components/_button.scss
.button {
  $bg: #1976d2;
  $padding: 12px 24px;
  
  background: $bg;
  padding: $padding;
  
  &:hover {
    background: darken($bg, 10%);
  }
}

// 3. In Chrome DevTools:
// - Open DevTools (F12)
// - Navigate to Sources tab
// - Expand "webpack://" or "scss://" folder
// - Find src/scss/components/_button.scss
// - See original SCSS with variables!

// 4. Inspect element shows:
// ┌─────────────────────────────────────┐
// │ Styles                              │
// ├─────────────────────────────────────┤
// │ .button                             │
// │   background: #1976d2;              │
// │   _button.scss:5                    │ ← Click to see SCSS
// │   padding: 12px 24px;               │
// │   _button.scss:6                    │
// └─────────────────────────────────────┘

// 5. Edit SCSS directly (with workspace):
// - Right-click source folder → "Add folder to workspace"
// - Allow access
// - Edit SCSS in DevTools Sources tab
// - Changes save to disk automatically
// - Sass watch mode recompiles
// - Page updates with new styles

// 6. Override styles temporarily:
// - In Elements → Styles pane
// - Add/modify CSS
// - See which SCSS file it came from
// - Update the actual SCSS file

Example: VS Code SCSS debugging setup

// .vscode/tasks.json - Compile task
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Watch Sass",
      "type": "shell",
      "command": "sass",
      "args": [
        "--watch",
        "--style=expanded",
        "--source-map",
        "src/scss:dist/css"
      ],
      "problemMatcher": ["$sass"],
      "isBackground": true,
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

// .vscode/launch.json - Debug configuration
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Debug in Chrome",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "sourceMaps": true,
      "preLaunchTask": "Watch Sass"
    }
  ]
}

// VS Code Extensions for SCSS:
// 1. Sass (.sass) - Syntax highlighting
// 2. SCSS IntelliSense - Autocomplete
// 3. SCSS Formatter - Code formatting
// 4. Live Sass Compiler - Auto-compile with output

// Usage:
// 1. Press Ctrl+Shift+B to start Sass watcher
// 2. Press F5 to launch debugger
// 3. Set breakpoints in JavaScript (not SCSS)
// 4. Inspect styles in integrated browser

Example: Source map debugging techniques

// Generate detailed source maps
sass --watch \
  --embed-sources \
  --source-map \
  --source-map-urls=relative \
  src/scss:dist/css

// Result: main.css.map
{
  "version": 3,
  "sourceRoot": "",
  "sources": [
    "../src/scss/main.scss",
    "../src/scss/_variables.scss",
    "../src/scss/components/_button.scss"
  ],
  "sourcesContent": [
    "@use 'variables';\n@use 'components/button';",
    "$primary: #1976d2;",
    ".button { background: $primary; }"
  ],
  "names": [],
  "mappings": "AAEA;EACE;EACA;;AAEA;EACE"
}

// Browser DevTools features:
// 1. Click CSS property → jumps to SCSS line
// 2. See variable name instead of computed value
// 3. Edit SCSS (with workspaces)
// 4. Search across SCSS files
// 5. Set CSS breakpoints (pause when style applied)

// Debugging without source maps:
// ❌ Elements → Styles shows:
//    main.css:234 { background: #1976d2; }
//    (No way to know which SCSS file)

// ✅ With source maps:
//    _button.scss:12 { background: $primary; }
//    (Shows exact SCSS file and line)

6. Common Error Patterns and Solutions

Error Pattern Cause Solution Prevention
Undefined Variable Typo or missing import Check spelling, import file Use linter, IDE autocomplete
Module Not Found Wrong path in @use/@import Verify file path Consistent file structure
Type Mismatch Wrong data type Validate input types Add type checks
Division Error Using / for division Use math.div() Always use math module
Circular Import A imports B, B imports A Refactor architecture One-way dependencies
@extend Outside Rule @extend at root level Move inside selector Use mixins instead

Example: Error prevention patterns

// 1. Defensive function design
@use 'sass:meta';
@use 'sass:math';

@function safe-divide($a, $b, $fallback: 0) {
  // Validate types
  @if meta.type-of($a) != 'number' or meta.type-of($b) != 'number' {
    @warn "safe-divide expects numbers, got: #{$a}, #{$b}";
    @return $fallback;
  }
  
  // Check for zero division
  @if $b == 0 {
    @warn "Division by zero, returning fallback: #{$fallback}";
    @return $fallback;
  }
  
  @return math.div($a, $b);
}

// 2. Null-safe map access
@function get-or-default($map, $key, $default: null) {
  @if not meta.type-of($map) == 'map' {
    @error "Expected map, got: #{meta.type-of($map)}";
  }
  
  @if map.has-key($map, $key) {
    @return map.get($map, $key);
  }
  
  @if $default == null {
    @warn "Key '#{$key}' not found in map and no default provided";
  }
  
  @return $default;
}

// 3. Runtime type checking
@mixin type-safe-property($property, $value, $allowed-types...) {
  $type: meta.type-of($value);
  
  @if not index($allowed-types, $type) {
    @error "#{$property} expects one of #{$allowed-types}, got: #{$type}";
  }
  
  #{$property}: $value;
}

// Usage
.element {
  @include type-safe-property('padding', 20px, 'number');
  @include type-safe-property('color', #000, 'color', 'string');
}

// 4. Import guard pattern
$_module-loaded: false !default;

@if $_module-loaded {
  @error "This module has already been loaded. Avoid importing it multiple times.";
}

$_module-loaded: true !global;

// 5. Version compatibility check
@if not function-exists('math.div') {
  @error "This code requires Sass 1.33.0 or higher for math.div(). " +
         "Please upgrade your Sass version.";
}

Example: Debugging helpers library

// _debug.scss - Reusable debugging utilities
@use 'sass:meta';
@use 'sass:map';
@use 'sass:list';

// Visual debugging overlay
@mixin debug-outline($color: red) {
  outline: 2px solid $color !important;
  outline-offset: -2px;
}

// Show all elements
@mixin debug-all($color: rgba(255, 0, 0, 0.2)) {
  * {
    @include debug-outline($color);
  }
}

// Print variable with formatting
@mixin debug-var($name, $value) {
  @debug "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
  @debug "Variable: #{$name}";
  @debug "  Type: #{meta.type-of($value)}";
  @debug "  Value: #{$value}";
  
  @if meta.type-of($value) == 'map' {
    @debug "  Keys: #{map.keys($value)}";
  } @else if meta.type-of($value) == 'list' {
    @debug "  Length: #{list.length($value)}";
  }
  @debug "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
}

// Performance timing
$_debug-timers: () !default;

@mixin start-timer($name) {
  // In real implementation, use timestamp
  @debug "[TIMER] Started: #{$name}";
}

@mixin end-timer($name) {
  @debug "[TIMER] Ended: #{$name}";
}

// Assertion helper
@mixin assert-equals($actual, $expected, $message: '') {
  @if $actual != $expected {
    @error "Assertion failed: #{$message}\n" +
           "  Expected: #{$expected}\n" +
           "  Actual: #{$actual}";
  } @else {
    @debug "✓ Assertion passed: #{$message}";
  }
}

// Usage examples
$primary: #1976d2;
@include debug-var('Primary Color', $primary);

@include start-timer('compilation');
// ... your code ...
@include end-timer('compilation');

@include assert-equals(10px + 5px, 15px, 'Basic math');

Example: Error recovery strategies

// Graceful degradation
@function get-color($theme, $key) {
  // Try to get from theme
  @if map.has-key($theme, $key) {
    @return map.get($theme, $key);
  }
  
  // Fallback to default colors
  @warn "Color '#{$key}' not found in theme, using default";
  
  $defaults: (
    primary: #1976d2,
    secondary: #dc004e,
    background: #ffffff,
    text: #000000
  );
  
  @if map.has-key($defaults, $key) {
    @return map.get($defaults, $key);
  }
  
  // Last resort
  @error "Color '#{$key}' not found in theme or defaults";
}

// Try-catch pattern (error suppression)
@function try-parse-number($value) {
  @if meta.type-of($value) == 'number' {
    @return $value;
  }
  
  // Try to parse string to number
  @if meta.type-of($value) == 'string' {
    @if str-index($value, 'px') {
      // In real implementation, parse the number
      @warn "String contains px, attempting conversion";
      @return 0px; // Placeholder
    }
  }
  
  @warn "Cannot parse '#{$value}' as number, returning 0";
  @return 0;
}

// Validation with auto-correction
@function validate-spacing($value) {
  // Must be positive
  @if $value < 0 {
    @warn "Spacing cannot be negative (#{$value}), using absolute value";
    @return abs($value);
  }
  
  // Warn about large values
  @if $value > 100px {
    @warn "Unusually large spacing value: #{$value}";
  }
  
  @return $value;
}

// Progressive enhancement
@mixin with-fallback($property, $modern-value, $fallback-value) {
  #{$property}: $fallback-value; // Fallback first
  
  @supports (#{$property}: #{$modern-value}) {
    #{$property}: $modern-value; // Modern override
  }
}

// Usage
.element {
  @include with-fallback(
    'display',
    'grid',
    'block'
  );
}

Error Handling Best Practices

  • @debug: Use for development logging and inspecting values
  • @warn: Use for deprecations and non-critical issues
  • @error: Use for critical failures that should stop compilation
  • Validate early: Check types and ranges at function entry
  • Meaningful messages: Include context, expected values, and solutions
  • Source maps: Essential for production debugging - map CSS back to SCSS
  • Stack traces: Read bottom-to-top to trace error origin
  • Defensive coding: Add guards, defaults, and null checks
Note: Enable source maps in development and staging environments for effective debugging. In production, disable them unless you need to debug live issues, as they expose your source code structure.