1
0
mirror of https://github.com/danog/amp.git synced 2025-01-22 13:21:16 +01:00

Allow recording stacktraces to debug double resolution

This commit is contained in:
Niklas Keller 2017-03-29 17:25:44 +02:00
parent 2f7e9a0746
commit 8caae2253f
3 changed files with 40 additions and 2 deletions

View File

@ -45,7 +45,8 @@
"Amp\\": "lib/"
},
"files": [
"lib/functions.php"
"lib/functions.php",
"lib/Internal/functions.php"
]
},
"autoload-dev": {

View File

@ -24,6 +24,9 @@ trait Placeholder {
/** @var callable|\Amp\Internal\ResolutionQueue|null */
private $onResolved;
/** @var null|array */
private $resolutionTrace;
/**
* @inheritdoc
*/
@ -75,9 +78,28 @@ trait Placeholder {
*/
private function resolve($value = null) {
if ($this->resolved) {
throw new \Error("Promise has already been resolved");
$message = "Promise has already been resolved";
if (isset($this->resolutionTrace)) {
$trace = formatStacktrace($this->resolutionTrace);
$message .= ". Previous resolution trace:\n\n{$trace}\n\n";
} else {
$message .= ", define const AMP_DEBUG_PLACEHOLDER_DOUBLE_RESOLUTION = true and enable assertions for a stacktrace of the previous resolution.";
}
throw new \Error($message);
}
assert((function () {
if (\defined("AMP_DEBUG_PLACEHOLDER_DOUBLE_RESOLUTION") && AMP_DEBUG_PLACEHOLDER_DOUBLE_RESOLUTION) {
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
array_shift($trace); // remove current closure
$this->resolutionTrace = $trace;
}
return true;
})());
if ($value instanceof ReactPromise) {
$value = Promise\adapt($value);
}

View File

@ -0,0 +1,15 @@
<?php
namespace Amp\Internal;
function formatStacktrace(array $trace): string {
return implode("\n", array_map(function ($e, $i) {
$line = "#{$i} {$e['file']}:{$e['line']} ";
if ($e["type"]) {
$line .= $e["class"] . $e["type"];
}
return $line . $e["function"] . "()";
}, $trace, array_keys($trace)));
}