...
Run Format

Source file src/runtime/error.go

Documentation: runtime

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import "internal/bytealg"
     8  
     9  // The Error interface identifies a run time error.
    10  type Error interface {
    11  	error
    12  
    13  	// RuntimeError is a no-op function but
    14  	// serves to distinguish types that are run time
    15  	// errors from ordinary errors: a type is a
    16  	// run time error if it has a RuntimeError method.
    17  	RuntimeError()
    18  }
    19  
    20  // A TypeAssertionError explains a failed type assertion.
    21  type TypeAssertionError struct {
    22  	_interface    *_type
    23  	concrete      *_type
    24  	asserted      *_type
    25  	missingMethod string // one method needed by Interface, missing from Concrete
    26  }
    27  
    28  func (*TypeAssertionError) RuntimeError() {}
    29  
    30  func (e *TypeAssertionError) Error() string {
    31  	inter := "interface"
    32  	if e._interface != nil {
    33  		inter = e._interface.string()
    34  	}
    35  	as := e.asserted.string()
    36  	if e.concrete == nil {
    37  		return "interface conversion: " + inter + " is nil, not " + as
    38  	}
    39  	cs := e.concrete.string()
    40  	if e.missingMethod == "" {
    41  		msg := "interface conversion: " + inter + " is " + cs + ", not " + as
    42  		if cs == as {
    43  			// provide slightly clearer error message
    44  			if e.concrete.pkgpath() != e.asserted.pkgpath() {
    45  				msg += " (types from different packages)"
    46  			} else {
    47  				msg += " (types from different scopes)"
    48  			}
    49  		}
    50  		return msg
    51  	}
    52  	return "interface conversion: " + cs + " is not " + as +
    53  		": missing method " + e.missingMethod
    54  }
    55  
    56  // An errorString represents a runtime error described by a single string.
    57  type errorString string
    58  
    59  func (e errorString) RuntimeError() {}
    60  
    61  func (e errorString) Error() string {
    62  	return "runtime error: " + string(e)
    63  }
    64  
    65  // plainError represents a runtime error described a string without
    66  // the prefix "runtime error: " after invoking errorString.Error().
    67  // See Issue #14965.
    68  type plainError string
    69  
    70  func (e plainError) RuntimeError() {}
    71  
    72  func (e plainError) Error() string {
    73  	return string(e)
    74  }
    75  
    76  type stringer interface {
    77  	String() string
    78  }
    79  
    80  func typestring(x interface{}) string {
    81  	e := efaceOf(&x)
    82  	return e._type.string()
    83  }
    84  
    85  // printany prints an argument passed to panic.
    86  // If panic is called with a value that has a String or Error method,
    87  // it has already been converted into a string by preprintpanics.
    88  func printany(i interface{}) {
    89  	switch v := i.(type) {
    90  	case nil:
    91  		print("nil")
    92  	case bool:
    93  		print(v)
    94  	case int:
    95  		print(v)
    96  	case int8:
    97  		print(v)
    98  	case int16:
    99  		print(v)
   100  	case int32:
   101  		print(v)
   102  	case int64:
   103  		print(v)
   104  	case uint:
   105  		print(v)
   106  	case uint8:
   107  		print(v)
   108  	case uint16:
   109  		print(v)
   110  	case uint32:
   111  		print(v)
   112  	case uint64:
   113  		print(v)
   114  	case uintptr:
   115  		print(v)
   116  	case float32:
   117  		print(v)
   118  	case float64:
   119  		print(v)
   120  	case complex64:
   121  		print(v)
   122  	case complex128:
   123  		print(v)
   124  	case string:
   125  		print(v)
   126  	default:
   127  		print("(", typestring(i), ") ", i)
   128  	}
   129  }
   130  
   131  // panicwrap generates a panic for a call to a wrapped value method
   132  // with a nil pointer receiver.
   133  //
   134  // It is called from the generated wrapper code.
   135  func panicwrap() {
   136  	pc := getcallerpc()
   137  	name := funcname(findfunc(pc))
   138  	// name is something like "main.(*T).F".
   139  	// We want to extract pkg ("main"), typ ("T"), and meth ("F").
   140  	// Do it by finding the parens.
   141  	i := bytealg.IndexByteString(name, '(')
   142  	if i < 0 {
   143  		throw("panicwrap: no ( in " + name)
   144  	}
   145  	pkg := name[:i-1]
   146  	if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
   147  		throw("panicwrap: unexpected string after package name: " + name)
   148  	}
   149  	name = name[i+2:]
   150  	i = bytealg.IndexByteString(name, ')')
   151  	if i < 0 {
   152  		throw("panicwrap: no ) in " + name)
   153  	}
   154  	if i+2 >= len(name) || name[i:i+2] != ")." {
   155  		throw("panicwrap: unexpected string after type name: " + name)
   156  	}
   157  	typ := name[:i]
   158  	meth := name[i+2:]
   159  	panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
   160  }
   161  

View as plain text