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 : 300 px ;
$height : 200 px ;
@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 * 1 rem ;
}
$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 : 576 px ,
md : 768 px ,
lg : 992 px ,
xl : 1200 px
);
@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 : 10 px 20 px ;
}
// 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 * 8 px ;
}
// 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 , 1 fr );
}
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 .
╷
8 │ background : 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
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
// 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 : 12 px 24 px ;
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' , 20 px , '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 : 2 px solid $color !important ;
outline-offset : -2 px ;
}
// 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 ( 10 px + 5 px , 15 px , '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 0 px ; // 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 > 100 px {
@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.